#include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QWidget(parent) { hDevice = NULL; UI = new mainwindowui(); time = new QTimer(); systemTime = 0x80000000; flag_sendTimePacket = false; packetToSend = new TCPacketToSend(); time->setInterval(1000); connect(UI->starDundeeStatusQueryRetryButton, SIGNAL(clicked()), this, SLOT(reTestSPWLink())); connect(this, SIGNAL(sendMessage(QString)), this->UI, SLOT(displayMessage(QString))); connect(this, SIGNAL(systemTimeHasChanged(long)), this->UI->systemTime, SLOT(systemTimeHasChanged(long))); connect(UI->startTimeButton, SIGNAL(clicked()), this, SLOT(sendTimecodesPeriodically())); connect(UI->sendTimecodeButton, SIGNAL(clicked()), this, SLOT(sendOneTimecode())); connect(UI->button_sendSystemTime, SIGNAL(clicked()), this, SLOT(sendSystemTime())); connect(UI->button_sendArbitraryTime, SIGNAL(clicked()), this, SLOT(sendArbitraryTime())); connect(this->time, SIGNAL(timeout()), this, SLOT(periodicalTimecodeTimeout())); this->setLayout(UI->layout()); } MainWindow::~MainWindow() { } void MainWindow::sendOneTimecode() { unsigned int result; U32 timecodeReg, val; if (hDevice==NULL) { result = Open(); } if (!getLinkStatus(UI->linkNumber_SPINBOX->value())) { emit sendMessage("ERR *** in sendOneTimecode *** stardundee brick not running"); } if(!USBSpaceWire_TC_EnableExternalTimecodeSelection(hDevice,0)) { emit sendMessage("ERR *** disable external timecode selection"); return; } if(!USBSpaceWire_TC_PerformTickIn(hDevice, 0)) { emit sendMessage("ERR *** in sendOneTimecode *** perform TickIn"); return; } // Read the timecode register if (CFGSpaceWire_GetTimecodeRegister(hDevice, &timecodeReg) != CFG_TRANSFER_SUCCESS) { emit sendMessage("Could not read the timecode register"); } else { CFGSpaceWire_TCGetValue(timecodeReg, &val); //emit sendMessage("The timecode value is currently: " + QString::number(val)); this->UI->currentTimecodeValue_LABEL->setText("Current Timecode Value: " + QString::number(val)); CFGSpaceWire_TCGetFlags(timecodeReg, &val); this->UI->currentTimecodeFlag_LABEL->setText("Current Timecode Flag: " + QString::number(val)); //emit sendMessage("The timecode flag value is currently: " + QString::number(val)); } } void MainWindow::sendTimecodesPeriodically() { if(time->isActive()) { time->stop(); this->UI->startTimeButton->setText("start sending timecodes periodically"); } else { time->start(); this->UI->startTimeButton->setText("stop sending timecodes periodically"); } } void MainWindow::periodicalTimecodeTimeout() { sendOneTimecode(); systemTime = systemTime + 1; if (flag_sendTimePacket == true) { flag_sendTimePacket = false; QTimer::singleShot(700, this, SLOT(sendTimePacketTimeout())); } emit(systemTimeHasChanged(systemTime)); } void MainWindow::sendTimePacketTimeout() { sendUpdateTime( systemTime + 1 ); } void MainWindow::sendSystemTime() { flag_sendTimePacket = true; } void MainWindow::sendArbitraryTime() { flag_sendTimePacket = true; systemTime = this->UI->arbitraryTime; emit (systemTimeHasChanged( systemTime)); } unsigned int MainWindow::Open() { U32 dwTickEnableStatus; if (!USBSpaceWire_Open(&hDevice, UI->usbDeviceNumber_SPINBOX->value())) // Open the USB device { emit sendMessage("ERR *** in Open *** USBSpaceWire_Open(&hDevice, 0))"); return 0; } emit sendMessage("OK *** in Open *** USBSpaceWire_Open successful, device number: " + QString::number(UI->usbDeviceNumber_SPINBOX->value())); USBSpaceWire_EnableNetworkMode(hDevice, 0); // deactivate the network mode CFGSpaceWire_EnableRMAP(1); // Enable the use of RMAP for the StarDundee brick configuration CFGSpaceWire_SetRMAPDestinationKey(0x20); // Set the destination key expected by STAR-Dundee devices // Set the path and return path to the device CFGSpaceWire_StackClear(); CFGSpaceWire_AddrStackPush(0); CFGSpaceWire_AddrStackPush(254); CFGSpaceWire_RetAddrStackPush(254); if (getLinkStatus(UI->linkNumber_SPINBOX->value())==0) { return UI->starDundeeStatusQueryDialog->exec(); } if (!USBSpaceWire_TC_Reset(hDevice)) { emit sendMessage("ERR *** in Open *** Could not reset timecodes\n"); } // Clear the tick enable register if (CFGSpaceWire_SetTickEnableStatus(hDevice, 6) != CFG_TRANSFER_SUCCESS) emit sendMessage("Could not clear the tick enable register"); else emit sendMessage("Cleared the tick enable register"); CFGSpaceWire_GetTickEnableStatus(hDevice, &dwTickEnableStatus); emit sendMessage("OK *** in Open *** CFGSpaceWire_GetTickEnableStatus, code is " + QString::number(dwTickEnableStatus, 2)); } unsigned int MainWindow::getLinkStatus(unsigned char link) { unsigned int resultOpen; U32 statusControl = 0, errorStatus = 0, portType = 0; U32 linkStatus = 0, operatingSpeed = 0, outputPortConnection = 0; char isLinkRunning = 0, isAutoStart = 0, isStart = 0, isDisabled = 0, isTristate = 0; if (hDevice==NULL) { resultOpen = Open(); } // Read the link status control register if (CFGSpaceWire_GetLinkStatusControl(hDevice, 1, &statusControl) != CFG_TRANSFER_SUCCESS) { emit sendMessage("Could not read link status control for link" + QString::number(link)); } else { // Display the link status control register properties CFGSpaceWire_LSPortType(statusControl, &portType); if (portType == CFG_CONFIGURATION_PORT) { CFGSpaceWire_LSConfigErrorStatus(statusControl, &errorStatus); //emit appendToLog("Configuration port error status = " + QString::number(errorStatus)); } else if (portType == CFG_SPACEWIRE_EXTERNAL_PORT) { CFGSpaceWire_LSExternalErrorStatus(statusControl, &errorStatus); //emit appendToLog("External port error status = " + QString::number(errorStatus)); } else { CFGSpaceWire_LSErrorStatus(statusControl, &errorStatus); //emit appendToLog("SpaceWire link error status = " + QString::number(errorStatus)); } CFGSpaceWire_LSLinkState(statusControl, &linkStatus); CFGSpaceWire_LSIsLinkRunning(statusControl, &isLinkRunning); CFGSpaceWire_LSIsAutoStart(statusControl, &isAutoStart); CFGSpaceWire_LSIsStart(statusControl, &isStart); CFGSpaceWire_LSIsDisabled(statusControl, &isDisabled); CFGSpaceWire_LSIsTristate(statusControl, &isTristate); CFGSpaceWire_LSOperatingSpeed(statusControl, &operatingSpeed); CFGSpaceWire_LSOutputPortConnection(statusControl, &outputPortConnection); //emit appendToLog("The link state is = " + QString::number(linkStatus)); //emit appendToLog("The link is running = " + QString::number(isLinkRunning)); //emit appendToLog("The autostart bit is enabled = " + QString::number(isAutoStart)); //emit appendToLog("The start bit is enabled = " + QString::number(isStart)); //emit appendToLog("The link is disabled = " + QString::number(isDisabled)); //emit appendToLog("The tri-state bit is enabled = " + QString::number(isAutoStart)); //emit appendToLog("The operating speed is = " + QString::number(operatingSpeed)); //emit appendToLog("This port is currently connected to output port = " + QString::number(outputPortConnection)); } if (linkStatus == 5) return 1; else return 0; } void MainWindow::reTestSPWLink() // SLOT { if (getLinkStatus(UI->linkNumber_SPINBOX->value())) { UI->starDundeeStatusQueryDialog->accept(); } } void MainWindow::sendUpdateTime(long time) { Packet_TC_LFR_UPDATE_TIME_t packet; unsigned char crcAsTwoBytes[2]; packet.packetID[0] = (unsigned char) (TC_LFR_PACKET_ID >> 8); packet.packetID[1] = (unsigned char) (TC_LFR_PACKET_ID ); packet.packetSequenceControl[0] = (unsigned char) (TC_LFR_PACKET_SEQUENCE_CONTROL >> 8); packet.packetSequenceControl[1] = (unsigned char) (TC_LFR_PACKET_SEQUENCE_CONTROL ); packet.packetLength[0] = (unsigned char) (PACKET_LENGTH_TC_LFR_UPDATE_TIME >> 8); packet.packetLength[1] = (unsigned char) (PACKET_LENGTH_TC_LFR_UPDATE_TIME ); packet.ccsdsSecHeaderFlag_pusVersion_ack = 0x19; packet.serviceType = TC_TYPE_LFR_UPDATE_TIME; packet.serviceSubType = TC_SUBTYPE_UPDATE_TIME; packet.sourceID = SID_DEFAULT; packet.cp_rpw_time[0] = (unsigned char) (time >> 24); packet.cp_rpw_time[1] = (unsigned char) (time >> 16); packet.cp_rpw_time[2] = (unsigned char) (time >> 8); packet.cp_rpw_time[3] = (unsigned char) (time); packet.cp_rpw_time[4] = 0; // fine time MSB packet.cp_rpw_time[5] = 0; // fine time LSB packetToSend->GetCRCAsTwoBytes((unsigned char*) &packet, crcAsTwoBytes, PACKET_LENGTH_TC_LFR_UPDATE_TIME + CCSDS_TC_TM_PACKET_OFFSET - 2); packet.crc[0] = crcAsTwoBytes[0]; packet.crc[1] = crcAsTwoBytes[1]; WriteSPW((char*) &packet, PACKET_LENGTH_TC_LFR_UPDATE_TIME + CCSDS_TC_TM_PACKET_OFFSET, CCSDS_NODE_ADDRESS, CCSDS_USER_APP); } unsigned int MainWindow::WriteSPW(char *Value, unsigned int count, char targetLogicalAddress, char userApplication) { char protocoleIdentifier = 0x02; char reserved = 0x00; char *SPWData; unsigned int totalSize; if (count>248) { emit sendMessage("WARNING === in function WRITE of rmapplugin *** CCSDS packet size > 248 bytes\n"); return 1; } if ( getLinkStatus( this->UI->linkNumber_SPINBOX->value() ) == 0 ) { emit sendMessage("WARNING === in function WriteSPW of StarDundee *** SPW link not running\n"); return 1; } totalSize = count + 4 + PATH_ADDRESSING_OFFSET; // The StarDundee brick is in PATH addressing SPWData = (char*) malloc(totalSize); // SPW HEADER SPWData[0] = this->UI->linkNumber_SPINBOX->value(); // 1 by default, value can be 1 or 2 SPWData[0+PATH_ADDRESSING_OFFSET] = targetLogicalAddress; SPWData[1+PATH_ADDRESSING_OFFSET] = protocoleIdentifier; SPWData[2+PATH_ADDRESSING_OFFSET] = reserved; SPWData[3+PATH_ADDRESSING_OFFSET] = userApplication; // CCSDS PACKET for (unsigned int i = 0; i