|
|
#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<count; i++)
|
|
|
{
|
|
|
SPWData[i+4+PATH_ADDRESSING_OFFSET] = Value[i];
|
|
|
}
|
|
|
|
|
|
//****************
|
|
|
// SEND THE PACKET
|
|
|
result = USBSpaceWire_SendPacket(hDevice,
|
|
|
SPWData,
|
|
|
totalSize,
|
|
|
BWAIT_1, &pIdentifier);
|
|
|
if (result != TRANSFER_SUCCESS)
|
|
|
{
|
|
|
emit sendMessage("ERROR *** WriteSPW when sending packet of size "
|
|
|
+ QString::number(totalSize) +", with code: " + QString::number(result));
|
|
|
USBSpaceWire_FreeSend(hDevice, pIdentifier);
|
|
|
free(SPWData);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
//**************
|
|
|
// Free the send
|
|
|
USBSpaceWire_FreeSend(hDevice, pIdentifier);
|
|
|
free(SPWData);
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
|
|