diff --git a/include/AmptekHardwareInterface.h b/include/AmptekHardwareInterface.h index 2fdc0b0966225a823fbd5bb0774d629e3ae5bcc2..a4416a673fc862ce7927186c1554a33b88bca2ec 100644 --- a/include/AmptekHardwareInterface.h +++ b/include/AmptekHardwareInterface.h @@ -44,14 +44,19 @@ public: bool UpdateStatus() {return updateStatus(-1);}; bool EnableListMode(std::string targetfile); + bool ResetListModeTimer(); bool DisableListMode(); + bool StartCommtestStreaming(uint16_t min_channel,uint16_t max_channel, + uint16_t increment, uint16_t rate); + bool StopCommtestStreaming(); + int FastCount(double max_age_ms = 100); int SlowCount(double max_age_ms = 100); double DeadTime(double max_age_ms = 100); double AccTime(double max_age_ms = 100); double RealTime(double max_age_ms = 100); - int FirmwareMajor(double max_age_ms = 1000000); + int FirmwareMajor(double max_age_ms = 1000000); int FirmwareMinor(double max_age_ms = 1000000); int FirmwareBuild(double max_age_ms = 1000000); int FpgaMajor(double max_age_ms = 1000000); diff --git a/include/AmptekUsbConnectionHandler.h b/include/AmptekUsbConnectionHandler.h index 250b626ee03a8a89f17cc0137fc8a8bd792e6ced..ceea013270df21112b4103b6403461423cb61dc9 100644 --- a/include/AmptekUsbConnectionHandler.h +++ b/include/AmptekUsbConnectionHandler.h @@ -3,7 +3,7 @@ #include "AmptekConnectionHandler.h" #include "libusb-1.0/libusb.h" - +#include <mutex> #define MAX_USB_OUT_PACKET_SIZE 520 #define MAX_USB_IN_PACKET_SIZE 32768 //defined by the amptek standard @@ -29,6 +29,7 @@ private: void CloseUsbDevice(libusb_device_handle * devh); byte* input_buffer; + std::mutex comm_mutex; }; #endif \ No newline at end of file diff --git a/include/packet.h b/include/packet.h index 47a57d2307464f026f8211fb0881a8e9648211d0..3870be6967a6367212e330ca1ebb393245c45dd5 100644 --- a/include/packet.h +++ b/include/packet.h @@ -80,7 +80,7 @@ enum PID2_SUBTYPE_STATUS_RESPONSE{ }; enum PID2_SUBTYPE_SPECTRUM_RESPONSE{ DP5_P2_SPECTRUM_RESPONSE_SPECTRUM256 = 0x01, - DP5_P2_SPECTRUM_SPECTRUM256_STATUS = 0x02, + DP5_P2_SPECTRUM_RESPONSE_SPECTRUM256_STATUS = 0x02, DP5_P2_SPECTRUM_RESPONSE_SPECTRUM512 = 0x03, DP5_P2_SPECTRUM_RESPONSE_SPECTRUM512_STATUS = 0x04, DP5_P2_SPECTRUM_RESPONSE_SPECTRUM1024 = 0x05, diff --git a/python/AmptekHardwareInterface.py b/python/AmptekHardwareInterface.py index 6813727078a55b9d7af4abf8f61826c5f7856381..9e494939473b0d591f6e9122d0bf3c96d292752b 100644 --- a/python/AmptekHardwareInterface.py +++ b/python/AmptekHardwareInterface.py @@ -661,9 +661,18 @@ class AmptekHardwareInterface(object): def EnableListMode(self, targetfile): return _AmptekHardwareInterface.AmptekHardwareInterface_EnableListMode(self, targetfile) + def ResetListModeTimer(self): + return _AmptekHardwareInterface.AmptekHardwareInterface_ResetListModeTimer(self) + def DisableListMode(self): return _AmptekHardwareInterface.AmptekHardwareInterface_DisableListMode(self) + def StartCommtestStreaming(self, min_channel, max_channel, increment, rate): + return _AmptekHardwareInterface.AmptekHardwareInterface_StartCommtestStreaming(self, min_channel, max_channel, increment, rate) + + def StopCommtestStreaming(self): + return _AmptekHardwareInterface.AmptekHardwareInterface_StopCommtestStreaming(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 ae30ab8ed49bd317c8b875e70b55e88a91d82826..f8c3852194a6bc32d0395364fb28c136de20aebc 100644 --- a/python/AmptekHardwareInterface_wrap.cpp +++ b/python/AmptekHardwareInterface_wrap.cpp @@ -5582,6 +5582,22 @@ SWIGINTERN std::vector< unsigned int >::iterator std_vector_Sl_unsigned_SS_int_S SWIGINTERN std::vector< unsigned int >::iterator std_vector_Sl_unsigned_SS_int_Sg__erase__SWIG_1(std::vector< unsigned int > *self,std::vector< unsigned int >::iterator first,std::vector< unsigned int >::iterator last){ return self->erase(first, last); } SWIGINTERN std::vector< unsigned int >::iterator std_vector_Sl_unsigned_SS_int_Sg__insert__SWIG_0(std::vector< unsigned int > *self,std::vector< unsigned int >::iterator pos,std::vector< unsigned int >::value_type const &x){ return self->insert(pos, x); } SWIGINTERN void std_vector_Sl_unsigned_SS_int_Sg__insert__SWIG_1(std::vector< unsigned int > *self,std::vector< unsigned int >::iterator pos,std::vector< unsigned int >::size_type n,std::vector< unsigned int >::value_type const &x){ self->insert(pos, n, x); } + +SWIGINTERN int +SWIG_AsVal_unsigned_SS_short (PyObject * obj, unsigned short *val) +{ + unsigned long v; + int res = SWIG_AsVal_unsigned_SS_long (obj, &v); + if (SWIG_IsOK(res)) { + if ((v > USHRT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = static_cast< unsigned short >(v); + } + } + return res; +} + #ifdef __cplusplus extern "C" { #endif @@ -14767,6 +14783,28 @@ fail: } +SWIGINTERN PyObject *_wrap_AmptekHardwareInterface_ResetListModeTimer(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_ResetListModeTimer",&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_ResetListModeTimer" "', argument " "1"" of type '" "AmptekHardwareInterface *""'"); + } + arg1 = reinterpret_cast< AmptekHardwareInterface * >(argp1); + result = (bool)(arg1)->ResetListModeTimer(); + 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 ; @@ -14789,6 +14827,86 @@ fail: } +SWIGINTERN PyObject *_wrap_AmptekHardwareInterface_StartCommtestStreaming(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { + PyObject *resultobj = 0; + AmptekHardwareInterface *arg1 = (AmptekHardwareInterface *) 0 ; + uint16_t arg2 ; + uint16_t arg3 ; + uint16_t arg4 ; + uint16_t arg5 ; + void *argp1 = 0 ; + int res1 = 0 ; + unsigned short val2 ; + int ecode2 = 0 ; + unsigned short val3 ; + int ecode3 = 0 ; + unsigned short val4 ; + int ecode4 = 0 ; + unsigned short val5 ; + int ecode5 = 0 ; + PyObject * obj0 = 0 ; + PyObject * obj1 = 0 ; + PyObject * obj2 = 0 ; + PyObject * obj3 = 0 ; + PyObject * obj4 = 0 ; + bool result; + + if (!PyArg_ParseTuple(args,(char *)"OOOOO:AmptekHardwareInterface_StartCommtestStreaming",&obj0,&obj1,&obj2,&obj3,&obj4)) 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_StartCommtestStreaming" "', argument " "1"" of type '" "AmptekHardwareInterface *""'"); + } + arg1 = reinterpret_cast< AmptekHardwareInterface * >(argp1); + ecode2 = SWIG_AsVal_unsigned_SS_short(obj1, &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "AmptekHardwareInterface_StartCommtestStreaming" "', argument " "2"" of type '" "uint16_t""'"); + } + arg2 = static_cast< uint16_t >(val2); + ecode3 = SWIG_AsVal_unsigned_SS_short(obj2, &val3); + if (!SWIG_IsOK(ecode3)) { + SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "AmptekHardwareInterface_StartCommtestStreaming" "', argument " "3"" of type '" "uint16_t""'"); + } + arg3 = static_cast< uint16_t >(val3); + ecode4 = SWIG_AsVal_unsigned_SS_short(obj3, &val4); + if (!SWIG_IsOK(ecode4)) { + SWIG_exception_fail(SWIG_ArgError(ecode4), "in method '" "AmptekHardwareInterface_StartCommtestStreaming" "', argument " "4"" of type '" "uint16_t""'"); + } + arg4 = static_cast< uint16_t >(val4); + ecode5 = SWIG_AsVal_unsigned_SS_short(obj4, &val5); + if (!SWIG_IsOK(ecode5)) { + SWIG_exception_fail(SWIG_ArgError(ecode5), "in method '" "AmptekHardwareInterface_StartCommtestStreaming" "', argument " "5"" of type '" "uint16_t""'"); + } + arg5 = static_cast< uint16_t >(val5); + result = (bool)(arg1)->StartCommtestStreaming(arg2,arg3,arg4,arg5); + resultobj = SWIG_From_bool(static_cast< bool >(result)); + return resultobj; +fail: + return NULL; +} + + +SWIGINTERN PyObject *_wrap_AmptekHardwareInterface_StopCommtestStreaming(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_StopCommtestStreaming",&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_StopCommtestStreaming" "', argument " "1"" of type '" "AmptekHardwareInterface *""'"); + } + arg1 = reinterpret_cast< AmptekHardwareInterface * >(argp1); + result = (bool)(arg1)->StopCommtestStreaming(); + 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 ; @@ -17309,7 +17427,10 @@ static PyMethodDef SwigMethods[] = { { (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_ResetListModeTimer", _wrap_AmptekHardwareInterface_ResetListModeTimer, METH_VARARGS, NULL}, { (char *)"AmptekHardwareInterface_DisableListMode", _wrap_AmptekHardwareInterface_DisableListMode, METH_VARARGS, NULL}, + { (char *)"AmptekHardwareInterface_StartCommtestStreaming", _wrap_AmptekHardwareInterface_StartCommtestStreaming, METH_VARARGS, NULL}, + { (char *)"AmptekHardwareInterface_StopCommtestStreaming", _wrap_AmptekHardwareInterface_StopCommtestStreaming, 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 34e67ad9f7123f6bfb2709c90ceb74a4b4abdf71..0693641aab21b5fa924464bba60ab9402ce08e8a 100644 --- a/src/AmptekHardwareInterface.cpp +++ b/src/AmptekHardwareInterface.cpp @@ -249,7 +249,7 @@ bool AmptekHardwareInterface::updateSpectrum(double max_age_ms){ switch( spectrumResponse.at(PID2) ){ case DP5_P2_SPECTRUM_RESPONSE_SPECTRUM256: with_status = false; // not break! use the respose with status setting the length - case DP5_P2_SPECTRUM_SPECTRUM256_STATUS: + case DP5_P2_SPECTRUM_RESPONSE_SPECTRUM256_STATUS: spectrum_length=256; break; @@ -340,6 +340,7 @@ bool AmptekHardwareInterface::EnableListMode(std::string targetfile){ streamfile.open( targetfile, ios::binary ); //f.write( static_cast <char*> ( &(pts.count) ), sizeof( unsigned ) ); listmode_flag = true; + ResetListModeTimer(); list_reader_thread = new std::thread([&](){ while(listmode_flag){ try{ @@ -372,10 +373,44 @@ bool AmptekHardwareInterface::DisableListMode(){ delete list_reader_thread; } +bool AmptekHardwareInterface::ResetListModeTimer(){ + try{ + expectAcknowledge(connection_handler->sendAndReceive( Packet::DP5_PKT_REQUEST_CLEAR_LIST_TIMER) ); + } + catch(AmptekException& e){ + + std::cerr<< "Failed clearing list-mode timer: " << e.what() << std::endl; + return false; + } +} - +bool AmptekHardwareInterface::StartCommtestStreaming(uint16_t min_channel,uint16_t max_channel, + uint16_t increment, uint16_t rate) +{ + // convert from rate (cts/sec) to number of fpga clock cycles between two events + uint32_t period = std::max(8., 1./( rate * FpgaClock()*1e-9 ) ); + try{ + Packet commtest_packet = Packet::generateCommtestStreamingRequest(min_channel, max_channel, increment, period); + expectAcknowledge(connection_handler->sendAndReceive( Packet::DP5_PKT_REQUEST_STOP_STREAM_COMMTEST) ); + } + catch(AmptekException& e){ + + std::cerr<< "Failed stopping comm test: " << e.what() << std::endl; + return false; + } +} +bool AmptekHardwareInterface::StopCommtestStreaming(){ + try{ + expectAcknowledge(connection_handler->sendAndReceive( Packet::DP5_PKT_REQUEST_STOP_STREAM_COMMTEST) ); + } + catch(AmptekException& e){ + + std::cerr<< "Failed stopping comm test: " << e.what() << std::endl; + return false; + } +} diff --git a/src/AmptekSimulatorConnectionHandler.cpp b/src/AmptekSimulatorConnectionHandler.cpp index 0db55e7b86b82f5578e7c081f04df3c9b6c44a1e..48a2443419a163fdce791922bc1edb80ec1a237b 100644 --- a/src/AmptekSimulatorConnectionHandler.cpp +++ b/src/AmptekSimulatorConnectionHandler.cpp @@ -49,7 +49,7 @@ Packet AmptekSimulatorConnectionHandler::sendAndReceive( const Packet& request){ p.setPid1( DP5_P1_SPECTRUM_RESPONSE ); switch (speclen){ case 256: - p.setPid2( DP5_P2_SPECTRUM_SPECTRUM256_STATUS ); + p.setPid2( DP5_P2_SPECTRUM_RESPONSE_SPECTRUM256_STATUS ); break; case 512: p.setPid2( DP5_P2_SPECTRUM_RESPONSE_SPECTRUM512_STATUS ); diff --git a/src/AmptekUsbConnectionHandler.cpp b/src/AmptekUsbConnectionHandler.cpp index bd9d9d024723e2a22c22288eddde1792edb7358d..c971028455e79a825a05084193e87ba830b86791 100644 --- a/src/AmptekUsbConnectionHandler.cpp +++ b/src/AmptekUsbConnectionHandler.cpp @@ -97,6 +97,7 @@ Packet AmptekUsbConnectionHandler::sendAndReceive( const Packet& request){ if ( request.size() > MAX_USB_OUT_PACKET_SIZE ){ throw AmptekException( "Cannot send Packets larger than "+ std::to_string(MAX_USB_OUT_PACKET_SIZE) + " bytes" ); } + std::lock_guard<std::mutex> comm_lock(comm_mutex); int bytes_transferred; int result = libusb_bulk_transfer(usb_handle, PX5_USB_BULK_OUT_ENDPOINT, (byte*) &(request.at(0)), request.size(), &bytes_transferred, 1000); std::string error_msg;