diff --git a/src/Makefile b/src/Makefile index f4e68d682384f6ff1ed5cee2a67bdc16d6f0ee3f..cdf0f2bbf12055bb45e4a5c25f9344978265d4dc 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 268b7342cf8ef9159a5a9c297576076216d74f1d..66a65e0f97af717cd688071677fe0acbdfe16d08 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 55758ccd72631fc63ba852185ed3a63e88af2dc3..44eb9612195dd77f29c1b5cd2b5c25e323f9daf8 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 b18b4c4e64e37c7097d15e6db125b4f3c1ed04b5..c9479effe62bc0bf2f81bbb0ceff048429a1060c 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 0000000000000000000000000000000000000000..7a7f50b15f377f16f0c5a1afde043e79a2c9ae3a --- /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 41fb3c3c7e4c87ca8470ecfcefb3815fcf9453b9..db68ba46f4f5691f00276e92a49489a5891f0b09 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 b22e282b23530fe0fe551240e57938663594e349..267a6c7d7d7032ae39886a42cfaf53841b024996 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; -}