From 54f99b8c3acfa3adef04cded213f3365e6450829 Mon Sep 17 00:00:00 2001
From: Dinyar Rabady <dinyar.rabady@cern.ch>
Date: Fri, 23 Sep 2022 12:50:35 +0200
Subject: [PATCH] Replace VIO board reset with SCONE one

Belongs to #14.
---
 src/Makefile            |  2 +-
 src/WZDmaInputFilter.cc | 10 ++++---
 src/WZDmaInputFilter.h  |  3 ++-
 src/scdaq.cc            |  3 ++-
 src/tools.cc            | 42 +++++++++++++++++++++++++++++
 src/tools.h             |  7 +++++
 src/wz_dma.c            | 58 -----------------------------------------
 7 files changed, 61 insertions(+), 64 deletions(-)
 create mode 100644 src/tools.cc

diff --git a/src/Makefile b/src/Makefile
index f4e68d68..cdf0f2bb 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -12,7 +12,7 @@
 TARGET = scdaq
 
 # source files
-SOURCES = config.cc DmaInputFilter.cc elastico.cc FileDmaInputFilter.cc InputFilter.cc OutputBySize.cc OutputByOrbit.cc processor.cc scdaq.cc session.cc slice.cc WZDmaInputFilter.cc MicronDmaInputFilter.cc
+SOURCES = config.cc DmaInputFilter.cc elastico.cc FileDmaInputFilter.cc InputFilter.cc OutputBySize.cc OutputByOrbit.cc processor.cc scdaq.cc session.cc slice.cc tools.cc WZDmaInputFilter.cc MicronDmaInputFilter.cc
 C_SOURCES = wz_dma.c
 
 # work out names of object files from sources
diff --git a/src/WZDmaInputFilter.cc b/src/WZDmaInputFilter.cc
index 268b7342..66a65e0f 100644
--- a/src/WZDmaInputFilter.cc
+++ b/src/WZDmaInputFilter.cc
@@ -12,8 +12,12 @@
 #include "log.h"
 #include "tools.h"
 
-WZDmaInputFilter::WZDmaInputFilter(size_t packetBufferSize, size_t nbPacketBuffers, ctrl &control)
-    : InputFilter(packetBufferSize, nbPacketBuffers, control) {
+WZDmaInputFilter::WZDmaInputFilter(size_t packetBufferSize, size_t nbPacketBuffers, ctrl &control,
+                                   config &conf)
+    : InputFilter(packetBufferSize, nbPacketBuffers, control),
+      sconeHost_{conf.getSconeHost()},
+      sconePort_{conf.getSconePort()},
+      sconeBoard_{conf.getSconeBoard()} {
   // Initialize the DMA subsystem
   if (wz_init(&dma_) < 0) {
     std::string msg = "Cannot initialize WZ DMA device";
@@ -111,7 +115,7 @@ inline ssize_t WZDmaInputFilter::read_packet(char **buffer, size_t bufferSize) {
       // Oversized packet is usually sign of link problem
       // Let's try to reset the board
       LOG(ERROR) << "Going to reset the board:";
-      if (wz_reset_board() < 0) {
+      if (tools::reset_board(sconeHost_, sconePort_, sconeBoard_) < 0) {
         LOG(ERROR) << "Reset failed";
       } else {
         LOG(ERROR) << "Reset finished";
diff --git a/src/WZDmaInputFilter.h b/src/WZDmaInputFilter.h
index 55758ccd..44eb9612 100644
--- a/src/WZDmaInputFilter.h
+++ b/src/WZDmaInputFilter.h
@@ -5,13 +5,14 @@
 #include <memory>
 
 #include "InputFilter.h"
+#include "config.h"
 #include "tbb/pipeline.h"
 #include "tbb/tick_count.h"
 #include "wz_dma.h"
 
 class WZDmaInputFilter : public InputFilter {
  public:
-  WZDmaInputFilter(size_t packetBufferSize, size_t nbPacketBuffers, ctrl &control);
+  WZDmaInputFilter(size_t packetBufferSize, size_t nbPacketBuffers, ctrl &control, config &conf);
   virtual ~WZDmaInputFilter();
 
  protected:
diff --git a/src/scdaq.cc b/src/scdaq.cc
index b18b4c4e..c9479eff 100644
--- a/src/scdaq.cc
+++ b/src/scdaq.cc
@@ -59,7 +59,8 @@ int run_pipeline(int nbThreads, ctrl &control, config &conf) {
 
   } else if (input == config::InputType::WZDMA) {
     // Create WZ DMA reader
-    input_filter = std::make_shared<WZDmaInputFilter>(packetBufferSize, nbPacketBuffers, control);
+    input_filter =
+        std::make_shared<WZDmaInputFilter>(packetBufferSize, nbPacketBuffers, control, conf);
 
   } else if (input == config::InputType::MICRONDMA) {
     // create MicronDmaInputFilter reader
diff --git a/src/tools.cc b/src/tools.cc
new file mode 100644
index 00000000..7a7f50b1
--- /dev/null
+++ b/src/tools.cc
@@ -0,0 +1,42 @@
+#include "tools.h"
+
+/*
+ * This function is just used to silence libcurl (see below)
+ */
+static size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) {
+  return size * nmemb;
+}
+
+/*
+ * Helper function to reset the board via SCONE
+ */
+int tools::reset_board(std::string host, std::string port, std::string board) {
+  std::string url{"http://" + host + ":" + port + "/" + board + "/reset_board/write"};
+  CURL *curl;
+  curl = curl_easy_init();
+  if (curl) {
+    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
+    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
+    curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
+    curl_easy_setopt(curl, CURLOPT_POST, 1);
+    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "value=1");  // Set reset to high
+    // To suppress the command line output of received data we need to pass in
+    // this callback function.
+    std::string dummy;
+    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &dummy);
+    CURLcode res = curl_easy_perform(curl);
+    if (res != 0) {
+      return res;
+    }
+    sleep(1);
+    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "value=0");  // Deassert reset
+    res = curl_easy_perform(curl);
+    if (res != 0) {
+      return res;
+    }
+    curl_easy_cleanup(curl);
+  } else {
+    return -1;
+  }
+  return 0;
+}
diff --git a/src/tools.h b/src/tools.h
index 41fb3c3c..db68ba46 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -5,8 +5,10 @@
  * Some useful functions
  */
 
+#include <curl/curl.h>
 #include <limits.h>
 #include <sys/stat.h>
+#include <unistd.h>  // TODO: This could eventually be replaced by chrono and thread when we move to a more modern C++ compiler.
 
 #include <cstring>
 #include <iostream>
@@ -38,6 +40,11 @@ inline const std::string strerror() { return tools::strerror(errno); }
  */
 inline const std::string strerror(const std::string &msg) { return msg + ": " + tools::strerror(); }
 
+/*
+ * Helper function to reset the board via SCONE
+ */
+int reset_board(std::string host, std::string port, std::string board);
+
 /*
  * Various filesystem related utilities (will be removed once moved to C++17, or
  * rewritten with boost)
diff --git a/src/wz_dma.c b/src/wz_dma.c
index b22e282b..267a6c7d 100644
--- a/src/wz_dma.c
+++ b/src/wz_dma.c
@@ -152,61 +152,3 @@ inline void wz_stop_source(struct wz_private* wz)
 	wz->usr_regs[0x10000/4] = 0;
 	asm volatile ("" : : : "memory");
 }
-
-
-#include <stdio.h> 
-#include <arpa/inet.h>
-
-/*
- * Normally, one should write to a register. But because we don't have a support for register for
- * the moment, we use a server connected to Vivado to do a reset
- */ 
-int wz_reset_board()
-{
-    struct sockaddr_in saddr_in;
-    int sock;
-    char buf[12];
-    int bytes_read;
-
-    // Fill the server address
-    inet_aton("127.0.0.1", &(saddr_in.sin_addr));
-    saddr_in.sin_family = AF_INET;
-    saddr_in.sin_port = htons(12345);
-
-    //print out IP address
-    printf("Server IP:  %s\n", inet_ntoa(saddr_in.sin_addr));
-
-    if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-        PERROR("Socket");
-        return -1;
-    }
-
-    // Connect socket to the server
-    if (connect(sock, (struct sockaddr *) &saddr_in, sizeof(struct sockaddr_in)) < 0) {
-        PERROR("Connect");
-        goto error;
-    }
-
-    if (send(sock, "reset\n", 6, 0) < 0) {
-        PERROR("Send");
-        goto error;
-    }
-
-    if ((bytes_read = recv(sock, buf, sizeof(buf) - 1, 0)) < 0) {
-        PERROR("Recv");
-        goto error;
-    }
-
-    // Put null terminating character
-    buf[bytes_read] = 0;
-    printf("Received '%s'\n", buf);
-
-    close(sock);
-
-    printf("Finished\n");
-    return 0;
-
-error:
-    close(sock);
-    return -1;
-}
-- 
GitLab