diff --git a/include/AmptekHardwareInterface.h b/include/AmptekHardwareInterface.h index eec1eee1dd64fd94102d972223fbc60200188d50..2fdc0b0966225a823fbd5bb0774d629e3ae5bcc2 100644 --- a/include/AmptekHardwareInterface.h +++ b/include/AmptekHardwareInterface.h @@ -2,6 +2,8 @@ #define AmptekHardwareInterface_h #include "types.h" #include <chrono> +#include <thread> +#include <fstream> #include "AmptekConnectionHandler.h" @@ -41,6 +43,9 @@ public: bool SetTextConfiguration(std::vector<std::string> commands); bool UpdateStatus() {return updateStatus(-1);}; + bool EnableListMode(std::string targetfile); + bool DisableListMode(); + int FastCount(double max_age_ms = 100); int SlowCount(double max_age_ms = 100); double DeadTime(double max_age_ms = 100); @@ -83,9 +88,14 @@ private: std::chrono::time_point<std::chrono::system_clock> last_status_update_time; std::chrono::time_point<std::chrono::system_clock> last_spectrum_update_time; + bool listmode_flag; + AmptekState current_state = NOT_CONNECTED; AmptekConnectionHandler* connection_handler = nullptr; + + std::thread* list_reader_thread = nullptr; + std::ofstream streamfile; }; diff --git a/include/packet.h b/include/packet.h index cce243fff82607af7149768e3dd000754868dfd6..47a57d2307464f026f8211fb0881a8e9648211d0 100644 --- a/include/packet.h +++ b/include/packet.h @@ -31,7 +31,7 @@ enum PID1_TYPE{ DP5_P1_SCA_REQUEST = 0x04, DP5_P1_TEXTCONFIG_REQUEST = 0x20, DP5_P1_COMMAND_REQUEST = 0xF0, - DP5_P1_COMTEST_REQUEST = 0xF1, + DP5_P1_COMMTEST_REQUEST = 0xF1, DP5_P1_STATUS_RESPONSE = 0x80, DP5_P1_SPECTRUM_RESPONSE = 0x81, @@ -70,7 +70,11 @@ enum PID2_SUBTYPE_COMMAND_REQUEST{ DP5_P2_COMMAND_REQUEST_CANCEL_BUFFER = 0x1F, DP5_P2_COMMAND_REQUEST_KEEP_ALIVE_NO_SHARE = 0x21, }; - +enum PID2_SUBTYPE_COMMTEST_REQUEST{ + DP5_P2_COMMTEST_REQUEST_ACK = 0xF1, + DP5_P2_COMMTEST_REQUEST_STREAM = 0xF2, + DP5_P2_COMMTEST_REQUEST_ECHO = 0xF3, +}; enum PID2_SUBTYPE_STATUS_RESPONSE{ DP5_P2_STATUS_RESPONSE_INFO = 0x01, }; @@ -173,6 +177,7 @@ public: static const Packet DP5_PKT_REQUEST_CANCEL_SEQ_BUFFERING; static const Packet DP5_PKT_REQUEST_LIST_DATA; static const Packet DP5_PKT_REQUEST_CLEAR_LIST_TIMER; + static const Packet DP5_PKT_REQUEST_STOP_STREAM_COMMTEST; static const Packet gernerateSetConfigurationRequest(std::string text_configuration); static const Packet gernerateGetConfigurationRequest(std::string text_configuration); @@ -181,6 +186,9 @@ public: static const Packet generateBufferAndClearRequest(uint16_t buffer_index); static const Packet generateGetBufferRequest(uint16_t buffer_index); + static const Packet generateCommtestStreamingRequest(uint16_t min_channel,uint16_t max_channel, + uint16_t increment, uint16_t period); + }; #endif diff --git a/python/AmptekHardwareInterface.py b/python/AmptekHardwareInterface.py index 8ee86f1fab569c5788e7473e0d8d2d46979a6fd8..6813727078a55b9d7af4abf8f61826c5f7856381 100644 --- a/python/AmptekHardwareInterface.py +++ b/python/AmptekHardwareInterface.py @@ -658,6 +658,12 @@ class AmptekHardwareInterface(object): def UpdateStatus(self): return _AmptekHardwareInterface.AmptekHardwareInterface_UpdateStatus(self) + def EnableListMode(self, targetfile): + return _AmptekHardwareInterface.AmptekHardwareInterface_EnableListMode(self, targetfile) + + def DisableListMode(self): + return _AmptekHardwareInterface.AmptekHardwareInterface_DisableListMode(self) + def FastCount(self, max_age_ms=100): return _AmptekHardwareInterface.AmptekHardwareInterface_FastCount(self, max_age_ms) diff --git a/python/AmptekHardwareInterface_wrap.cpp b/python/AmptekHardwareInterface_wrap.cpp index c6dcbfdc42c26d2ae4394f63bc8ec7b7b06c21da..ae30ab8ed49bd317c8b875e70b55e88a91d82826 100644 --- a/python/AmptekHardwareInterface_wrap.cpp +++ b/python/AmptekHardwareInterface_wrap.cpp @@ -14734,6 +14734,61 @@ fail: } +SWIGINTERN PyObject *_wrap_AmptekHardwareInterface_EnableListMode(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + AmptekHardwareInterface *arg1 = (AmptekHardwareInterface *) 0 ; + std::string arg2 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + bool result; + + if (!PyArg_ParseTuple(args,(char *)"OO:AmptekHardwareInterface_EnableListMode",&obj0,&obj1)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_AmptekHardwareInterface, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "AmptekHardwareInterface_EnableListMode" "', argument " "1"" of type '" "AmptekHardwareInterface *""'"); + } + arg1 = reinterpret_cast< AmptekHardwareInterface * >(argp1); + { + std::string *ptr = (std::string *)0; + int res = SWIG_AsPtr_std_string(obj1, &ptr); + if (!SWIG_IsOK(res) || !ptr) { + SWIG_exception_fail(SWIG_ArgError((ptr ? res : SWIG_TypeError)), "in method '" "AmptekHardwareInterface_EnableListMode" "', argument " "2"" of type '" "std::string""'"); + } + arg2 = *ptr; + if (SWIG_IsNewObj(res)) delete ptr; + } + result = (bool)(arg1)->EnableListMode(arg2); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_AmptekHardwareInterface_DisableListMode(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + AmptekHardwareInterface *arg1 = (AmptekHardwareInterface *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + PyObject * obj0 = 0 ; + bool result; + + if (!PyArg_ParseTuple(args,(char *)"O:AmptekHardwareInterface_DisableListMode",&obj0)) SWIG_fail; + res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_AmptekHardwareInterface, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "AmptekHardwareInterface_DisableListMode" "', argument " "1"" of type '" "AmptekHardwareInterface *""'"); + } + arg1 = reinterpret_cast< AmptekHardwareInterface * >(argp1); + result = (bool)(arg1)->DisableListMode(); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + SWIGINTERN PyObject *_wrap_AmptekHardwareInterface_FastCount__SWIG_0(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { PyObject *resultobj = 0; AmptekHardwareInterface *arg1 = (AmptekHardwareInterface *) 0 ; @@ -17253,6 +17308,8 @@ static PyMethodDef SwigMethods[] = { { (char *)"AmptekHardwareInterface_SetPresetCounts", _wrap_AmptekHardwareInterface_SetPresetCounts, METH_VARARGS, NULL}, { (char *)"AmptekHardwareInterface_SetTextConfiguration", _wrap_AmptekHardwareInterface_SetTextConfiguration, METH_VARARGS, NULL}, { (char *)"AmptekHardwareInterface_UpdateStatus", _wrap_AmptekHardwareInterface_UpdateStatus, METH_VARARGS, NULL}, + { (char *)"AmptekHardwareInterface_EnableListMode", _wrap_AmptekHardwareInterface_EnableListMode, METH_VARARGS, NULL}, + { (char *)"AmptekHardwareInterface_DisableListMode", _wrap_AmptekHardwareInterface_DisableListMode, METH_VARARGS, NULL}, { (char *)"AmptekHardwareInterface_FastCount", _wrap_AmptekHardwareInterface_FastCount, METH_VARARGS, NULL}, { (char *)"AmptekHardwareInterface_SlowCount", _wrap_AmptekHardwareInterface_SlowCount, METH_VARARGS, NULL}, { (char *)"AmptekHardwareInterface_DeadTime", _wrap_AmptekHardwareInterface_DeadTime, METH_VARARGS, NULL}, diff --git a/src/AmptekHardwareInterface.cpp b/src/AmptekHardwareInterface.cpp index 0af63f3afcbf51a8194147b66c42913fa03a03b1..34e67ad9f7123f6bfb2709c90ceb74a4b4abdf71 100644 --- a/src/AmptekHardwareInterface.cpp +++ b/src/AmptekHardwareInterface.cpp @@ -335,6 +335,52 @@ if (connection_handler != nullptr){ +bool AmptekHardwareInterface::EnableListMode(std::string targetfile){ + + streamfile.open( targetfile, ios::binary ); + //f.write( static_cast <char*> ( &(pts.count) ), sizeof( unsigned ) ); + listmode_flag = true; + list_reader_thread = new std::thread([&](){ + while(listmode_flag){ + try{ + Packet listResponse = connection_handler->sendAndReceive( Packet::DP5_PKT_REQUEST_LIST_DATA ); + //std::cout << spectrumResponse.size() << std::endl; + if (listResponse.at(PID1) != DP5_P1_DATA_RESPONSE ) + { + throw AmptekException("Response Packet is not of type DATA_RESPONSE: " + listResponse.toString()); + } + if( listResponse.at(PID2) != DP5_P2_DATA_RESPONSE_LISTDATA && listResponse.at(PID2) != DP5_P2_DATA_RESPONSE_LISTDATA_FULL ){ + throw AmptekException("Response Packet is not of subtype LISTDATA: " + listResponse.toString()); + } + //write the packet without the sync and checksum to file : [PID1,PID2,LEN_MSB;LEN_LSB,DATA_0,....,DATA_N] + streamfile.write( reinterpret_cast<char*>( &listResponse[PID1] ), listResponse.dataLength + 4 ); + + } + catch(AmptekException& e){ + std::cerr << e.what() << std::endl; + } + std::this_thread::sleep_for(std::chrono::microseconds(100)); + } + }); + return true; +} + +bool AmptekHardwareInterface::DisableListMode(){ + listmode_flag = false; + list_reader_thread->join(); + streamfile.close(); + delete list_reader_thread; +} + + + + + + + + + + diff --git a/src/packet.cpp b/src/packet.cpp index b2ea60fc2851269b5b926e069bb30598d817265f..4a0964daa3057acd9901bc0bbabaef5648b45bc6 100644 --- a/src/packet.cpp +++ b/src/packet.cpp @@ -20,6 +20,9 @@ const Packet Packet::DP5_PKT_REQUEST_RESTART_SEQ_BUFFERING = Packet( DP5_P1_COMM const Packet Packet::DP5_PKT_REQUEST_CANCEL_SEQ_BUFFERING = Packet( DP5_P1_COMMAND_REQUEST , DP5_P2_COMMAND_REQUEST_CANCEL_BUFFER , nullptr, 0); const Packet Packet::DP5_PKT_REQUEST_CLEAR_LIST_TIMER = Packet( DP5_P1_COMMAND_REQUEST , DP5_P2_COMMAND_REQUEST_CLEAR_TIMER , nullptr, 0); + +const Packet Packet::DP5_PKT_REQUEST_STOP_STREAM_COMMTEST = Packet( DP5_P1_COMMTEST_REQUEST , DP5_P2_COMMTEST_REQUEST_STREAM , nullptr, 0 ); + const Packet Packet::gernerateSetConfigurationRequest(std::string text_configuration){ word16 len = text_configuration.size(); byte data[len]; @@ -51,6 +54,21 @@ const Packet Packet::generateGetBufferRequest(uint16_t buffer_index){ data[1] = buffer_index; return Packet( DP5_P1_SPECTRUM_REQUEST, DP5_P2_SPECTRUM_REQUEST_GET_BUFFER, data, 2 ); } +const Packet Packet::generateCommtestStreamingRequest(uint16_t min_channel,uint16_t max_channel, + uint16_t increment, uint16_t period) +{ + byte data[8]; + data[0] = min_channel >> 8; + data[1] = min_channel; + data[2] = max_channel >> 8; + data[3] = max_channel; + data[4] = increment >> 8; + data[5] = increment; + data[6] = period >> 8; + data[7] = period; + return Packet( DP5_P1_COMMTEST_REQUEST , DP5_P2_COMMTEST_REQUEST_STREAM , data, 8 ); + +} Packet::Packet():vector<byte>(), dataLength(0)