#include "GUI.h" #include "SocketClient.h" #include "ViewEvent.h" #include "math.h" // Quit application when clicking close button on window void fad::closeEvent(QCloseEvent *) { qApp->quit(); } // +++ Connecting or disconnecting from client +++ void fad::MakeConnection() { if(Socket[0]->state() == QAbstractSocket::ConnectedState) { ManualDisconnect = true; for (int i=0; idisconnectFromHost(); return; } for (int i=0; isetEnabled(false); Socket[i]->connectToHost(IPAddress->text(),Port->value() + i); Socket[i]->waitForConnected(SOCKET_TIMEOUT); Connect->setEnabled(true); if (Socket[i]->state() != QAbstractSocket::ConnectedState) { QMessageBox::warning(this, "fad Message","Could not connect to host.",QMessageBox::Ok); return; } } Connect->setText("Disconnect"); ConnectAction->setText("Disconnect"); Port->setEnabled(false); IPAddress->setEnabled(false); Command->setEnabled(true); ManualDisconnect = false; } // +++ Send command to socket +++ void fad::SendToSocket() { char *Buffer = Command->text().toAscii().data(); int i; unsigned short CMD_Buffer[512]; unsigned char CMD_Str[16]; unsigned short CMD_Num = 1; int val, num; if (strncmp (Buffer, "r", 2) == 0) { CMD_Buffer[0] = htons (CMD_Start); printf ("# Start Run ->\n"); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); } else if (strncmp (Buffer, "s", 2) == 0) { CMD_Buffer[0] = htons (CMD_Stop); printf ("# Stop Run ->\n"); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); } else if (strncmp (Buffer, "sz", 3) == 0) { CMD_Buffer[0] = 0x0000; printf ("# Send 0x0000 ->\n"); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); } else if (strncmp (Buffer, "de\n", 2) == 0) { CMD_Buffer[0] = htons (CMD_DENABLE); printf ("# domino wave enabled ->\n"); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); } else if (strncmp (Buffer, "dd\n", 2) == 0) { CMD_Buffer[0] = htons (CMD_DDISABLE); printf ("# domino wave disabled ->\n"); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); } else if (strncmp (Buffer, "dr\n", 2) == 0) { CMD_Buffer[0] = htons (CMD_DWRITE_RUN); printf ("# DWRITE HIGH->\n"); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); } else if (strncmp (Buffer, "ds\n", 2) == 0) { CMD_Buffer[0] = htons (CMD_DWRITE_STOP); printf ("# DWRITE LOW ->\n"); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); } else if (strncmp (Buffer, "t", 2) == 0) { CMD_Buffer[0] = htons (CMD_Trigger); printf ("# Trigger ->\n"); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); } else if (strncmp (Buffer, "tc", 3) == 0) { CMD_Buffer[0] = htons (CMD_Trigger_C); printf ("# Continuous Trigger ->\n"); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); } else if (strncmp (Buffer, "ts", 3) == 0) { CMD_Buffer[0] = htons (CMD_Trigger_S); printf ("# Stop Trigger ->\n"); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); } else if (strncmp (Buffer, "sclkon\n", 6) == 0) { CMD_Buffer[0] = htons (CMD_SCLK_ON); printf ("# SCLK ENABLED ->\n"); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); } else if (strncmp (Buffer, "sclkoff\n", 7) == 0) { CMD_Buffer[0] = htons (CMD_SCLK_OFF); printf ("# SCLK DISABLED ->\n"); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); } // Set ROI value else if (strncmp (Buffer, "sr ", 3) == 0) { CMD_Num = 0; if (sscanf (Buffer, "%3s %i %i", CMD_Str, &num, &val) == 3) { if ((num >= 0) & (num <= MAX_ROINUM) & (val >= 0) & (val <= MAX_ROIVAL)) { printf ("# Set ROI %d to %d ->\n", num, val); CMD_Buffer[0] = htons (CMD_Write | (BADDR_ROI + num)); CMD_Buffer[1] = htons (val); printf ("# 0x%.4X 0x%.4X\n", ntohs (CMD_Buffer[0]), ntohs (CMD_Buffer[1])); CMD_Num = 2; } else { printf ("Out of range\n"); printf ("Usage: sr NUM VAL: Set ROI NUM (0-%d) to VAL (0-%d)\n", MAX_ROINUM, MAX_ROIVAL); } } else { printf ("Usage: sr NUM VAL: Set ROI NUM (0-%d) to VAL (0-%d)\n", MAX_ROINUM, MAX_ROIVAL); } } // Set all ROIs else if (strncmp (Buffer, "sra ", 4) == 0) { CMD_Num = 0; if (sscanf (Buffer, "%4s %i", CMD_Str, &val) == 2) { if ((val >= 0) & (val <= MAX_ROIVAL)) { printf ("# Set all ROIs to %d ->\n", val); for (i = 0; i < (MAX_ROINUM + 1); i++) { CMD_Buffer[i * 2] = htons (CMD_Write | (BADDR_ROI + i)); CMD_Buffer[(i * 2) + 1] = htons (val); CMD_Num += 2; } for (i = 0; i < ((MAX_ROINUM + 1) * 2); i += 8) { printf ("# 0x%.4X 0x%.4X 0x%.4X 0x%.4X 0x%.4X 0x%.4X 0x%.4X 0x%.4X\n", ntohs (CMD_Buffer[i]), ntohs (CMD_Buffer[i + 1]), ntohs (CMD_Buffer[i + 2]), ntohs (CMD_Buffer[i + 3]), ntohs (CMD_Buffer[i + 4]), ntohs (CMD_Buffer[i + 5]), ntohs (CMD_Buffer[i + 6]), ntohs (CMD_Buffer[i + 7])); } } else { printf ("Out of range\n"); printf ("Usage: sra VAL: Set all ROIs to VAL (0-%d)\n", MAX_ROIVAL); } } else { printf ("Usage: sra VAL: Set all ROIs to VAL (0-%d)\n", MAX_ROIVAL); } } // Set DAC value else if (strncmp (Buffer, "sd ", 3) == 0) { CMD_Num = 0; if (sscanf (Buffer, "%3s %i %i", CMD_Str, &num, &val) == 3) { if ((num >= 0) & (num <= MAX_DACNUM) & (val >= 0) & (val <= MAX_DACVAL)) { printf ("# Set DAC %d to %d ->\n", num, val); CMD_Buffer[0] = htons (CMD_Write | (BADDR_DAC + num)); CMD_Buffer[1] = htons (val); printf ("# 0x%.4X 0x%.4X\n", ntohs (CMD_Buffer[0]), ntohs (CMD_Buffer[1])); CMD_Num = 2; } else { printf ("Out of range\n"); printf ("Usage: sd NUM VAL: Set DAC NUM (0-%d) to VAL (0-%d)\n", MAX_DACNUM, MAX_DACVAL); } } else { printf ("Usage: sd NUM VAL: Set DAC NUM (0-%d) to VAL (0-%d)\n", MAX_DACNUM, MAX_DACVAL); } } // Set address to value else if (strncmp (Buffer, "sa ", 3) == 0) { CMD_Num = 0; if (sscanf (Buffer, "%4s %i %i", CMD_Str, &num, &val) == 3) { if ((num >= 0) & (num <= MAX_ADDR) & (val >= 0) & (val <= MAX_VAL)) { printf ("# Set ADDR %d to %d ->\n", num, val); CMD_Buffer[0] = htons (CMD_Write | num); CMD_Buffer[1] = htons (val); printf ("# 0x%.4X 0x%.4X\n", ntohs (CMD_Buffer[0]), ntohs (CMD_Buffer[1])); CMD_Num = 2; } else { printf ("Out of range\n"); printf ("Usage: sa NUM VAL: Set addr NUM (0-%d) to VAL (0-%d)\n", MAX_ADDR, MAX_VAL); } } else { printf ("Usage: raw NUM VAL: Set addr NUM (0-%d) to VAL (0-%d)\n", MAX_ADDR, MAX_VAL); } } // Send value else if (strncmp (Buffer, "sv ", 3) == 0) { CMD_Num = 0; if (sscanf (Buffer, "%4s %i", CMD_Str, &val) == 2) { if ((val >= 0) & (val <= MAX_VAL)) { printf ("# Send %d ->\n", val); CMD_Buffer[0] = htons (val); printf ("# 0x%.4X\n", ntohs (CMD_Buffer[0])); CMD_Num = 1; } else { printf ("Out of range\n"); printf ("Usage: sv VAL: Send VAL (0-%d)\n", MAX_VAL); } } else { printf ("Usage: sv VAL: Send VAL (0-%d)\n", MAX_VAL); } } // Anything else... , print help else { printf ("Commands:\n"); printf (" r: Start Run -- TODO\n"); printf (" s: Stop Run -- TODO\n"); printf (" t: Single Trigger\n\n"); printf (" de: DENABLE HIGH\n"); printf (" dd: DENABLE LOW\n"); printf (" dr: DWRITE HIGH\n"); printf (" ds: DWRITE LOW\n\n"); printf (" tc: Continuous Trigger\n"); printf (" ts: Stop Trigger\n"); printf (" sr NUM VAL: Set ROI NUM (0-35) to VAL (0-1024)\n"); printf (" sra VAL: Set all ROIs to VAL (0-1024)\n"); printf (" sd NUM VAL: Set DAC NUM (0-7) to VAL (0-65535)\n"); printf (" q: Quit\n"); printf ("\n"); printf (" Only for debugging:\n"); printf (" sa NUM VAL: Set addr NUM (0-255) to VAL (0-65535)\n"); printf (" sv VAL: Send VAL\n"); printf (" sz: Send 0x0000\n"); printf ("\n"); CMD_Num = 0; } // Clear output SocketOutput->clear(); for (int i=0; iwrite(Data)); Command->clear(); } // +++ Read data from socket and display +++ // // Structure interpreation taken from 'ViewEvent.cc' by Kai Warda. // void fad::ReadFromSocket() { QByteArray SocketData; // Add data to text display (hex) and to data array for (int Sckt=0; ScktreadAll(); if (SocketData.isEmpty()) continue; Data[Sckt].append(SocketData); // Print result printf("Got %d bytes from socket %d\n", (int) SocketData.size(), Sckt); SocketOutput->insertPlainText(SocketData.toHex()); // Check package length (measured in units of 2 bytes) EVNT_HEADER *Header = (EVNT_HEADER *) Data[Sckt].data(); if (Data[Sckt].size() != 2 * ntohs (Header->package_length)) continue; // read and print package header printf ("Start Package Flag: 0x%.4X\n", ntohs (Header->start_package_flag)); printf ("Package Length: 0x%.4X\n", ntohs (Header->package_length)); printf ("Version Number: 0x%.4X\n", ntohs (Header->version_no)); printf ("Trigger-ID: 0x%.8X\n", ntohl (Header->trigger_id)); printf ("Trigger Type: 0x%.2X\n", Header->trigger_type); printf ("Trigger CRC: 0x%.2X\n", Header->trigger_crc); printf ("Local Trigger-ID: 0x%.8X\n", ntohl (Header->local_trigger_id)); printf ("Local Trigger Type: 0x%.2X\n", Header->local_trigger_type); printf ("Local Trigger CRC: 0x%.2X\n", Header->local_trigger_crc); printf ("Board-ID: 0x%.4X\n", ntohs (Header->board_id)); for (int i = 0; i < 4; i++) { if ((ntohs (Header->drs_temperature[i]) & 0x8000) == 0x8000) { printf ("Temperature %d: %d\n", i, 0xE000 | (ntohs (Header->drs_temperature[i])) >> 3); } else printf ("Temperature %d: %d\n", i, ntohs (Header->drs_temperature[i]) >> 3); } // DAC Values, only if version > 0x0101 if (ntohs (Header->version_no) > 0x0101) { for (int i = 0; i < 8; i++) printf ("DAC %d: %d\n", i, ntohs (Header->dac[i])); } // read channels, no error checking... double *x, *y; CHANNEL *Channel = (CHANNEL *) (Data[Sckt].data() + sizeof(EVNT_HEADER)); unsigned int drs_index, channel_index; for (int i=0; ichannel_roi)]; y = new double [ntohs (Channel->channel_roi)]; int dummy; printf("ROI: %d\n", ntohs (Channel->channel_roi)); // print channel header printf ("\nChannel-ID: 0x%.4X\n", ntohs (Channel->channel_id)); printf ("Channel Start-Cell: 0x%.4X\n", ntohs (Channel->channel_start_cell)); printf ("Channel ROI: 0x%.4X\n", ntohs (Channel->channel_roi)); // print channel data printf ("Channel Data:\n"); unsigned short *ChannelData = (unsigned short *) &Channel->channel_adc_data; for (int j=0; jchannel_roi); j++) { x[j] = j* 50; dummy = ad9238ToInt( (short) ntohs (ChannelData[j]) ); y[j] = (double) dummy /2048.0 ; //printf ("%4d: 0x%.4x , 0x%.4x , %.4f \n", j, (short) ntohs (ChannelData[j]), dummy, y[j]); } printf ("channel %d: DRS[%d] is %d : ChannelCheckBox[%d] is %d\n" , i, drs_index, DRS[drs_index]->isChecked() , channel_index, ChannelCheckBox[channel_index]->isChecked() ); if (DRS[drs_index]->isChecked() && ChannelCheckBox[channel_index]->isChecked()) { // Plot data Signal[i]->setData(x, y, ntohs(Channel->channel_roi)); Signal[i]->show(); printf ("plotting\n" ); } else { Signal[i]->hide(); } delete[] x; delete[] y; // Move pointer to next channel Channel = (CHANNEL *) ((char *) Channel + (3 + ntohs (Channel->channel_roi)) * sizeof(unsigned short)); } // Recast to access last entries of event structure unsigned int *Pointer = (unsigned int *) Channel; // CRC, only if version > 0x0100 if (ntohs (Header->version_no) > 0x0100) { printf ("\nPackage CRC: 0x%.4X\n", ntohs (*(Pointer++))); } // end package flag printf ("\nEnd Package Flag: 0x%.4X\n\n", ntohs (*Pointer)); // Clear accumulated data array Data[Sckt].clear(); } // Loop over sockets } // +++ Reset graph axes to autoscale when fully unzoomed +++ void fad::HandleZoom(const QwtDoubleRect &) { if(Zoomer->zoomRectIndex() == 0) { Graph->setAxisAutoScale(QwtPlot::xBottom); Graph->setAxisAutoScale(QwtPlot::yLeft); } } // +++ Disconnect from socket +++ void fad::GotDisconnected() { Connect->setText("Connect"); ConnectAction->setText("Connect"); Port->setEnabled(true); IPAddress->setEnabled(true); Command->setEnabled(false); SocketOutput->clear(); if(!ManualDisconnect) QMessageBox::warning(this, "fad Message","Socket disconnected, maybe host gone.",QMessageBox::Ok); } //------------------------------------------------------------------ //**************************** All menus *************************** //------------------------------------------------------------------ void fad::MenuSave() { QString Filename = QFileDialog::getSaveFileName(this, "Filename of image", ".", "Image files (*.bmp *.jpg *.png *.ppm *.tiff *.xbm *.xpm);;All files (*)"); if (Filename.length()>0) { QPixmap Pixmap = QPixmap::grabWidget(Graph); if(!Pixmap.save(Filename)) { QMessageBox::warning(this, "fad Message","Could not write image file.",QMessageBox::Ok); remove(Filename.toAscii().data()); } } } void fad::MenuPrint() { QPrinter *Printer = new QPrinter; QPrintDialog *PrintDialog = new QPrintDialog(Printer, this); if (PrintDialog->exec() == QDialog::Accepted) { QPainter Painter(Printer); QPixmap Pixmap = QPixmap::grabWidget(Graph); Painter.drawPixmap(0, 0, Pixmap); } delete Printer; delete PrintDialog; } void fad::MenuSaveASCII() { QString Filename = QFileDialog::getSaveFileName(this, "Filename", ".", "Text files (*.txt *.ascii *.asc);;All files (*)"); if (Filename.length()>0) { QFile File(Filename); if (File.open(QFile::WriteOnly | QIODevice::Text | QFile::Truncate)) { QTextStream Stream(&File); for (int Count=0; CountdataSize(); i++) Stream << Signal[i]->y(i) << endl; Stream << endl; } } else { QMessageBox::warning(this, "fad Message","Could not write data to file.",QMessageBox::Ok); } } } /* ad9238ToDouble input: unsigned short code: 13bit ADC code in an 16bit data type unsigned short was chosen, because it is least subject to interpretation AD9238 is an 12bit ADC which in addition outputs an overflow bit. The overflow bit (OVFL) as well as the data bits 11 until 0 (D11..D0) are assembled in the unsigned short as follows: |bit15|bit14|bit13|bit12|bit11|bit10|bit9 |bit8 | | 0 | 0 | 0 |OVFL | D11 | D10 | D9 | D8 | |bit7 |bit6 |bit5 |bit4 |bit3 |bit2 |bit1 |bit0 | | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | D11..D0 are formatted as twos complement so: 0x000 = 0 ... 0x7FF = 2047 0x800 = -2048 ... 0xFFF = -1 Note: taking the overflow bit into account as well as the twos complement format. This is how overflows are coded: 0x7FF ist the largest positive 12bit number. therefore: 0x17FF = 0001.0111.1111.1111 = 6143 is the code for a positive overflow and 0x800 is the most negative 12bit number. now 0x1800 = 0001.1000.0000.0000 = 6144 is the code for an underflow. */ double fad::ad9238ToDouble(unsigned short code){ unsigned short upper_three_bit_mask = 0xE000; if ((code & upper_three_bit_mask) != 0x0000) // one of the upper three bits was set --> Error { fprintf (stderr, "error in ad9238ToDouble. 1 of 3 upper bits was set. code = 0x%4X" ,code); return nan(""); } // check for over- and underflow if (code == 0x17FF) // overflow return 2048; // this is the highest signed short + 1, indicating an overflow. if (code == 0x1800) // underflow return -2049; // this is the lowest signed short - 1, indicating an underflow. // note: bit shifting operator >> is smart. // when shifting a signed integer type to the right, the // sign bit is expanded: // 0x1800 << 4 = 0x8000 and then // 0x8000 >> 4 = 0xF800, when the type is a signed one. return double( (((short) code) << 4) >> 4); } double fad::ad9238ToDouble(short code){ unsigned short upper_three_bit_mask = 0xE000; if ((code & upper_three_bit_mask) != 0x0000) // one of the upper three bits was set --> Error { fprintf (stderr, "error in ad9238ToDouble. 1 of 3 upper bits was set. code = 0x%4X" ,code); return nan(""); } // check for over- and underflow if (code == 0x17FF) // overflow return 2048; // this is the highest signed short + 1, indicating an overflow. if (code == 0x1800) // underflow return -2049; // this is the lowest signed short - 1, indicating an underflow. // note: bit shifting operator >> is smart. // when shifting a signed integer type to the right, the // sign bit is expanded: // 0x1800 << 4 = 0x8000 and then // 0x8000 >> 4 = 0xF800, when the type is a signed one. return double( (( code) << 4) >> 4); } int fad::ad9238ToInt(short code){ unsigned short upper_three_bit_mask = 0xE000; if ((code & upper_three_bit_mask) != 0x0000) // one of the upper three bits was set --> Error { fprintf (stderr, "error in ad9238ToDouble. 1 of 3 upper bits was set. code = 0x%4X" ,code); return -10000; } // check for over- and underflow if (code == 0x17FF) // overflow return 2048; // this is the highest signed short + 1, indicating an overflow. if (code == 0x1800) // underflow return -2049; // this is the lowest signed short - 1, indicating an underflow. // note: bit shifting operator >> is smart. // when shifting a signed integer type to the right, the // sign bit is expanded: // 0x1800 << 4 = 0x8000 and then // 0x8000 >> 4 = 0xF800, when the type is a signed one. //return (( code) << 4) >> 4; // this doenst seem to work. // check if sign-bit (bit 11) is set if ( (code & 0x800) != 0) { // sign-bit is set -> number is negative code = code | 0xF000; // bits 12..15 are set } else { } return code; }