mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-07-09 11:10:50 +02:00
Merge branch 'developer' into dev/rx_disable_datastream_port
This commit is contained in:
@@ -21,11 +21,42 @@ jobs:
|
||||
cache: 'pip'
|
||||
- run: pip install pytest numpy colorama
|
||||
|
||||
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
# using a stable action version instead of latest to create/restore cache for now
|
||||
- uses: awalsh128/cache-apt-pkgs-action@v1.6.1
|
||||
with:
|
||||
packages: libhdf5-dev qtbase5-dev qt5-qmake libqt5svg5-dev libpng-dev libtiff-dev libfmt-dev
|
||||
version: 1.0
|
||||
|
||||
# verify packages restored from cache are installed.
|
||||
# This catches incomplete apt installs after cache restore.
|
||||
- name: Verify apt packages
|
||||
id: verify_packages
|
||||
run: |
|
||||
failed=""
|
||||
|
||||
for pkg in \
|
||||
libhdf5-dev \
|
||||
qtbase5-dev \
|
||||
qt5-qmake \
|
||||
libqt5svg5-dev \
|
||||
libpng-dev \
|
||||
libtiff-dev \
|
||||
libfmt-dev
|
||||
do
|
||||
if ! dpkg -s "$pkg" >/dev/null 2>&1; then
|
||||
echo "Missing: $pkg"
|
||||
failed="$failed $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
if [ -n "$failed" ]; then
|
||||
echo "Missing packages after cache restore: $failed. Try deleting the cache and rerunning the workflow."
|
||||
exit 1
|
||||
else
|
||||
echo "All apt packages are installed"
|
||||
fi
|
||||
|
||||
- name: Configure CMake
|
||||
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
|
||||
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
|
||||
|
||||
@@ -20,11 +20,37 @@ jobs:
|
||||
cache: 'pip'
|
||||
- run: pip install pytest numpy colorama pyzmq
|
||||
|
||||
- uses: awalsh128/cache-apt-pkgs-action@latest
|
||||
# using a stable action version instead of latest to create/restore cache for now
|
||||
- uses: awalsh128/cache-apt-pkgs-action@v1.6.1
|
||||
with:
|
||||
packages: libhdf5-dev libfmt-dev
|
||||
version: 1.0
|
||||
|
||||
# verify packages restored from cache are installed.
|
||||
# This catches incomplete apt installs after cache restore.
|
||||
- name: Verify apt packages
|
||||
id: verify_packages
|
||||
run: |
|
||||
failed=""
|
||||
|
||||
for pkg in \
|
||||
libhdf5-dev \
|
||||
libfmt-dev
|
||||
do
|
||||
if ! dpkg -s "$pkg" >/dev/null 2>&1; then
|
||||
echo "Missing: $pkg"
|
||||
failed="$failed $pkg"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$failed" ]; then
|
||||
echo "Missing packages after cache restore: $failed. Try deleting the cache and rerunning the workflow."
|
||||
exit 1
|
||||
else
|
||||
echo "All apt packages are installed"
|
||||
fi
|
||||
|
||||
|
||||
- name: Configure CMake
|
||||
run: |
|
||||
cmake -B ${{github.workspace}}/build \
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// SPDX-License-Identifier: LGPL-3.0-or-other
|
||||
// Copyright (C) 2021 Contributors to the SLS Detector Package
|
||||
#include "clogger.h"
|
||||
#include "sls/ansi.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h> // File control definitions
|
||||
#include <linux/i2c-dev.h> // I2C_SLAVE, __u8 reg
|
||||
#include <fcntl.h> // File control definitions
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h> // atoi
|
||||
#include <string.h> // memset
|
||||
@@ -12,80 +12,102 @@
|
||||
#include <termios.h> /* POSIX terminal control definitions */
|
||||
#include <unistd.h> // read, close
|
||||
|
||||
#define PORTNAME "/dev/ttyBF1"
|
||||
#define GOODBYE 200
|
||||
#define BUFFERSIZE 16
|
||||
#define I2C_DEVICE_FILE "/dev/i2c-0"
|
||||
#define I2C_DEVICE_ADDRESS 0x4C
|
||||
// #define I2C_DEVICE_ADDRESS 0x48
|
||||
#define I2C_REGISTER_ADDRESS 0x40
|
||||
#define PORTNAME "/dev/ttyBF1"
|
||||
#define GOODBYE 200
|
||||
#define BUFFERSIZE 16
|
||||
#define INFILE "/sys/devices/platform/i2c-bfin-twi.0/i2c-0/0-0048/in0_input"
|
||||
#define OUTFILE "/sys/devices/platform/i2c-bfin-twi.0/i2c-0/0-0048/out0_output"
|
||||
#define OUTENABLE \
|
||||
"/sys/devices/platform/i2c-bfin-twi.0/i2c-0/0-0048/out0_enable"
|
||||
|
||||
int i2c_open(const char *file, unsigned int addr) {
|
||||
|
||||
// device file
|
||||
int fd = open(file, O_RDWR);
|
||||
if (fd < 0) {
|
||||
LOG(logERROR, ("Warning: Unable to open file %s\n", file));
|
||||
int set_hv(int dac_value) {
|
||||
if ((dac_value > 255) || (dac_value < 0)) {
|
||||
LOG(logERROR, ("Invalid dac value %d\n", dac_value));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// device address
|
||||
if (ioctl(fd, I2C_SLAVE, addr & 0x7F) < 0) {
|
||||
LOG(logERROR, ("Warning: Unable to set slave address:0x%x \n", addr));
|
||||
return -2;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
dac_value = dac_value * 10;
|
||||
|
||||
int i2c_read() {
|
||||
|
||||
int fd = i2c_open(I2C_DEVICE_FILE, I2C_DEVICE_ADDRESS);
|
||||
__u8 reg = I2C_REGISTER_ADDRESS & 0xff;
|
||||
|
||||
unsigned char buf = reg;
|
||||
if (write(fd, &buf, 1) != 1) {
|
||||
LOG(logERROR,
|
||||
("Warning: Unable to write read request to register %d\n", reg));
|
||||
FILE *file;
|
||||
file = fopen(OUTFILE, "w");
|
||||
if (file == NULL) {
|
||||
perror("set_hv:");
|
||||
LOG(logERROR, ("Cannot open out0_output file\n"));
|
||||
return -1;
|
||||
}
|
||||
// read and update value (but old value read out)
|
||||
if (read(fd, &buf, 1) != 1) {
|
||||
LOG(logERROR, ("Warning: Unable to read register %d\n", reg));
|
||||
return -2;
|
||||
if (setvbuf(file, NULL, _IONBF, 0) != 0) {
|
||||
perror("set_hv:");
|
||||
LOG(logERROR, ("Cannot disable buffering\n"));
|
||||
return -1;
|
||||
}
|
||||
// read again to read the updated value
|
||||
if (read(fd, &buf, 1) != 1) {
|
||||
LOG(logERROR, ("Warning: Unable to read register %d\n", reg));
|
||||
return -2;
|
||||
if (fprintf(file, "%d", dac_value) < 1) {
|
||||
ferror(file);
|
||||
LOG(logERROR, ("Couldn't write to out0_output file\n"));
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int i2c_write(unsigned int value) {
|
||||
|
||||
__u8 val = value & 0xff;
|
||||
|
||||
int fd = i2c_open(I2C_DEVICE_FILE, I2C_DEVICE_ADDRESS);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
|
||||
__u8 reg = I2C_REGISTER_ADDRESS & 0xff;
|
||||
char buf[3];
|
||||
buf[0] = reg;
|
||||
buf[1] = val;
|
||||
if (write(fd, buf, 2) != 2) {
|
||||
LOG(logERROR,
|
||||
("Warning: Unable to write %d to register %d\n", val, reg));
|
||||
if (fclose(file) != 0) {
|
||||
perror("set_hv:");
|
||||
LOG(logERROR, ("Troubles closing out0_output file\n"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int enable_hv(int val) {
|
||||
if ((val > 1) || (val < 0))
|
||||
return -1;
|
||||
FILE *file;
|
||||
file = fopen(OUTENABLE, "w");
|
||||
if (file == NULL) {
|
||||
perror("enable_hv:");
|
||||
LOG(logERROR, ("Cannot open out0_enable file\n"));
|
||||
return -1;
|
||||
}
|
||||
if (setvbuf(file, NULL, _IONBF, 0) != 0) {
|
||||
perror("enable_hv:");
|
||||
LOG(logERROR, ("Cannot disable buffering\n"));
|
||||
return -1;
|
||||
}
|
||||
if (fprintf(file, "%d", val) < 1) {
|
||||
ferror(file);
|
||||
LOG(logERROR, ("Couldn't write to out0_enable file\n"));
|
||||
return -1;
|
||||
}
|
||||
if (fclose(file) != 0) {
|
||||
perror("enable_hv:");
|
||||
LOG(logERROR, ("Troubles closing out0_enable file\n"));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_hv() {
|
||||
int value;
|
||||
FILE *file;
|
||||
file = fopen(INFILE, "r");
|
||||
if (file == NULL) {
|
||||
perror("get_hv:");
|
||||
LOG(logERROR, ("Cannot open in0_input file\n"));
|
||||
return -1;
|
||||
}
|
||||
if (fscanf(file, "%d", &value) < 1) {
|
||||
ferror(file);
|
||||
LOG(logERROR, ("Couldn't read from in0_input file\n"));
|
||||
return -1;
|
||||
}
|
||||
if (fclose(file) != 0) {
|
||||
perror("get_hv:");
|
||||
LOG(logERROR, ("Troubles closing out0_enable file\n"));
|
||||
return -1;
|
||||
}
|
||||
return value / 10;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
enable_hv(0);
|
||||
set_hv(0);
|
||||
|
||||
int fd = open(PORTNAME, O_RDWR | O_NOCTTY | O_SYNC);
|
||||
if (fd < 0) {
|
||||
LOG(logERROR, ("Warning: Unable to open port %s\n", PORTNAME));
|
||||
@@ -126,7 +148,7 @@ int main(int argc, char *argv[]) {
|
||||
int ival = 0;
|
||||
char buffer[BUFFERSIZE];
|
||||
memset(buffer, 0, BUFFERSIZE);
|
||||
buffer[BUFFERSIZE - 1] = '\n';
|
||||
// buffer[BUFFERSIZE - 1] = '\n';
|
||||
LOG(logINFO, ("Ready...\n"));
|
||||
|
||||
while (ret != GOODBYE) {
|
||||
@@ -149,35 +171,51 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
// ok/ fail
|
||||
memset(buffer, 0, BUFFERSIZE);
|
||||
buffer[BUFFERSIZE - 1] = '\n';
|
||||
if (i2c_write(ival) < 0)
|
||||
strcpy(buffer, "fail ");
|
||||
// buffer[BUFFERSIZE - 1] = '\n';
|
||||
|
||||
if (set_hv(ival) < 0)
|
||||
strcpy(buffer, "fail\n");
|
||||
else if (enable_hv(ival > 0 ? 1 : 0) < 0)
|
||||
strcpy(buffer, "fail\n");
|
||||
else
|
||||
strcpy(buffer, "success ");
|
||||
strcpy(buffer, "success\n");
|
||||
/*
|
||||
if (i2c_write(ival) < 0)
|
||||
strcpy(buffer, "fail ");
|
||||
else
|
||||
strcpy(buffer, "success ");
|
||||
*/
|
||||
LOG(logINFO, ("Sending: '%s'\n", buffer));
|
||||
n = write(fd, buffer, BUFFERSIZE);
|
||||
n = write(fd, buffer, strlen(buffer)); // BUFFERSIZE);
|
||||
LOG(logDEBUG1, ("Sent %d Bytes\n", n));
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
ival = i2c_read();
|
||||
// ok/ fail
|
||||
memset(buffer, 0, BUFFERSIZE);
|
||||
buffer[BUFFERSIZE - 1] = '\n';
|
||||
ival = get_hv();
|
||||
if (ival < 0)
|
||||
strcpy(buffer, "fail ");
|
||||
strcpy(buffer, "fail\n");
|
||||
else
|
||||
strcpy(buffer, "success ");
|
||||
n = write(fd, buffer, BUFFERSIZE);
|
||||
strcpy(buffer, "success\n");
|
||||
/*
|
||||
ival = i2c_read();
|
||||
// ok/ fail
|
||||
memset(buffer, 0, BUFFERSIZE);
|
||||
buffer[BUFFERSIZE - 1] = '\n';
|
||||
if (ival < 0)
|
||||
strcpy(buffer, "fail ");
|
||||
else
|
||||
strcpy(buffer, "success ");
|
||||
*/
|
||||
n = write(fd, buffer, strlen(buffer)); // BUFFERSIZE);
|
||||
LOG(logINFO, ("Sending: '%s'\n", buffer));
|
||||
LOG(logDEBUG1, ("Sent %d Bytes\n", n));
|
||||
// value
|
||||
memset(buffer, 0, BUFFERSIZE);
|
||||
buffer[BUFFERSIZE - 1] = '\n';
|
||||
// buffer[BUFFERSIZE - 1] = '\n';
|
||||
if (ival >= 0) {
|
||||
LOG(logINFO, ("Sending: '%d'\n", ival));
|
||||
sprintf(buffer, "%d ", ival);
|
||||
n = write(fd, buffer, BUFFERSIZE);
|
||||
sprintf(buffer, "%d\n", ival);
|
||||
n = write(fd, buffer, strlen(buffer)); // BUFFERSIZE);
|
||||
LOG(logINFO, ("Sent %d Bytes\n", n));
|
||||
} else
|
||||
LOG(logERROR, ("%s\n", buffer));
|
||||
|
||||
@@ -41,9 +41,9 @@ $(PROGS): $(OBJS)
|
||||
|
||||
|
||||
hv9m_blackfin_server:9mhvserial_bf.c
|
||||
$(BLACKFIN_CC) -o hv9m_blackfin_server 9mhvserial_bf.c -Wall #-DVERBOSE
|
||||
$(BLACKFIN_CC) $(CFLAGS) -o hv9m_blackfin_server 9mhvserial_bf.c -Wall #-DVERBOSE
|
||||
mv hv9m_blackfin_server $(DESTDIR)
|
||||
rm hv9m_blackfin_server.gdb $(main_src)*.o $(md5_dir)*.o
|
||||
rm hv9m_blackfin_server.gdb
|
||||
|
||||
clean:
|
||||
rm -rf $(DESTDIR)/$(PROGS) *.o $(DESTDIR)/hv9m_blackfin_server $(main_src)*.o $(md5_dir)*.o
|
||||
|
||||
@@ -27,8 +27,8 @@ ClientSocket::ClientSocket(std::string stype, const std::string &host,
|
||||
|
||||
if (getaddrinfo(host.c_str(), nullptr, &hints, &result) != 0) {
|
||||
|
||||
|
||||
auto msg = fmt::format("Cannot resolve {} hostname: '{}'", to_lower(socketType), host);
|
||||
auto msg = fmt::format("Cannot resolve {} hostname: '{}'",
|
||||
to_lower(socketType), host);
|
||||
throwError(msg);
|
||||
}
|
||||
|
||||
@@ -43,9 +43,8 @@ ClientSocket::ClientSocket(std::string stype, const std::string &host,
|
||||
if (::connect(getSocketId(), (struct sockaddr *)&serverAddr,
|
||||
sizeof(serverAddr)) != 0) {
|
||||
freeaddrinfo(result);
|
||||
auto msg = fmt::format(
|
||||
"Cannot connect to {} on {}:{}\n",
|
||||
to_lower(socketType), host, port);
|
||||
auto msg = fmt::format("Cannot connect to {} on {}:{}\n",
|
||||
to_lower(socketType), host, port);
|
||||
|
||||
throwError(msg);
|
||||
}
|
||||
@@ -58,7 +57,8 @@ ClientSocket::ClientSocket(std::string sType, struct sockaddr_in addr)
|
||||
if (::connect(getSocketId(), (struct sockaddr *)&addr, sizeof(addr)) != 0) {
|
||||
char address[INET_ADDRSTRLEN];
|
||||
inet_ntop(AF_INET, &addr.sin_addr, address, INET_ADDRSTRLEN);
|
||||
auto msg = fmt::format("Cannot connect to {} on {}:{}", to_lower(socketType), address, addr.sin_port);
|
||||
auto msg = fmt::format("Cannot connect to {} on {}:{}",
|
||||
to_lower(socketType), address, addr.sin_port);
|
||||
throwError(msg);
|
||||
}
|
||||
}
|
||||
@@ -99,7 +99,8 @@ void ClientSocket::readReply(int &ret, void *retval, size_t retval_size) {
|
||||
}
|
||||
// debugging
|
||||
catch (SocketError &e) {
|
||||
auto msg = fmt::format("While reading reply from {} {}", to_lower(socketType), e.what());
|
||||
auto msg = fmt::format("While reading reply from {} {}",
|
||||
to_lower(socketType), e.what());
|
||||
throwError(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,10 +113,9 @@ int DataSocket::Send(const void *buffer, size_t size) {
|
||||
#endif
|
||||
Timer timer;
|
||||
while (bytes_sent < bytes_expected) {
|
||||
this_send = ::send(
|
||||
getSocketId(),
|
||||
reinterpret_cast<const char *>(buffer) + bytes_sent,
|
||||
bytes_expected - bytes_sent, send_flags);
|
||||
this_send = ::send(getSocketId(),
|
||||
reinterpret_cast<const char *>(buffer) + bytes_sent,
|
||||
bytes_expected - bytes_sent, send_flags);
|
||||
if (this_send < 0 && errno == EINTR)
|
||||
continue; // interrupted by a signal, retry
|
||||
if (this_send <= 0)
|
||||
|
||||
@@ -78,7 +78,7 @@ std::pair<std::string, uint16_t> ParseHostPort(const std::string &s) {
|
||||
std::string to_lower(const std::string &s) {
|
||||
std::string result = s;
|
||||
std::transform(result.begin(), result.end(), result.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
[](unsigned char c) { return std::tolower(c); });
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,11 +30,8 @@ std::vector<char> echo_server(uint16_t port, size_t bytes_to_send,
|
||||
std::vector<char> buffer(100, '\0');
|
||||
s.Receive(buffer.data(), buffer.size());
|
||||
|
||||
if (port==1960){
|
||||
struct linger ling = {
|
||||
.l_onoff = 1,
|
||||
.l_linger = 0
|
||||
};
|
||||
if (port == 1960) {
|
||||
struct linger ling = {.l_onoff = 1, .l_linger = 0};
|
||||
|
||||
auto fd = s.getSocketId();
|
||||
setsockopt(fd, SOL_SOCKET, SO_LINGER, &ling, sizeof ling);
|
||||
@@ -199,7 +196,6 @@ TEST_CASE("Receiving with a socket error throws and reports the error",
|
||||
CHECK_THAT(error_message, Catch::Matchers::Contains("read error:"));
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Socket crash?", "[support]") {
|
||||
std::vector<char> received_message(100, '\0');
|
||||
std::vector<char> sent_message(100, '\0');
|
||||
@@ -211,25 +207,20 @@ TEST_CASE("Socket crash?", "[support]") {
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
auto client = DetectorSocket("localhost", 1960);
|
||||
client.Send(sent_message.data(), sent_message.size());
|
||||
|
||||
|
||||
REQUIRE_THROWS(client.Receive(received_message.data(), received_message.size()));
|
||||
|
||||
//Now try to send more
|
||||
// client.Send(sent_message.data(), sent_message.size());
|
||||
|
||||
|
||||
REQUIRE_THROWS(
|
||||
client.Receive(received_message.data(), received_message.size()));
|
||||
|
||||
// Now try to send more
|
||||
// client.Send(sent_message.data(), sent_message.size());
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("ClientSocket throws on invalid hostname", "[support]") {
|
||||
CHECK_THROWS(ReceiverSocket("invalidhostname", 1950));
|
||||
CHECK_THROWS(DetectorSocket("invalidhostname", 1950));
|
||||
CHECK_THROWS(GuiSocket("invalidhostname", 1950));
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("Using DetectorSocket to talk to a Server Socket", "[support]") {
|
||||
constexpr uint16_t port = 1961;
|
||||
constexpr int fnum = F_GET_DETECTOR_TYPE;
|
||||
@@ -240,9 +231,8 @@ TEST_CASE("Using DetectorSocket to talk to a Server Socket", "[support]") {
|
||||
|
||||
auto client = DetectorSocket("localhost", port);
|
||||
int retval = 0;
|
||||
int ret =
|
||||
client.sendCommandThenRead(fnum, &arg, sizeof(arg), &retval,
|
||||
sizeof(retval));
|
||||
int ret = client.sendCommandThenRead(fnum, &arg, sizeof(arg), &retval,
|
||||
sizeof(retval));
|
||||
client.close();
|
||||
|
||||
auto server_received = s.get();
|
||||
@@ -294,8 +284,8 @@ TEST_CASE("Client cannot send the expected number of bytes", "[support]") {
|
||||
// Server accepts but never reads; it stays open until we tell it the
|
||||
// client is done, so it cannot close mid-transfer.
|
||||
std::atomic<bool> client_done{false};
|
||||
auto s = std::async(std::launch::async, non_reading_server, port,
|
||||
&client_done);
|
||||
auto s =
|
||||
std::async(std::launch::async, non_reading_server, port, &client_done);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
auto client = DetectorSocket("localhost", port);
|
||||
|
||||
@@ -148,8 +148,6 @@ TEST_CASE("to_lower does not modify the original string") {
|
||||
REQUIRE(original == "MixedCase");
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TEST_CASE("concat things not being strings")
|
||||
|
||||
} // namespace sls
|
||||
|
||||
Reference in New Issue
Block a user