mainwindow.cpp
416 lines
| 15.4 KiB
| text/x-c
|
CppLexer
r69 | #include "mainwindow.h" | |||
MainWindow::MainWindow(QWidget *parent) : | ||||
QWidget(parent) | ||||
{ | ||||
hDevice = NULL; | ||||
UI = new mainwindowui(); | ||||
time = new QTimer(); | ||||
systemTime = 0x80000000; | ||||
flag_sendSystemTimePacket = false; | ||||
flag_sendArbitraryTimePacket = false; | ||||
flag_sendTimecodesPeriodicallyStarDundee = 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(sendTimecodesPeriodicallyPC())); | ||||
connect(UI->startPeriodicalTimecode_StarDundee, SIGNAL(clicked()), | ||||
this, SLOT(sendTimecodesPeriodicallyStarDundee())); | ||||
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(UI->button_sendSystemTimeAndTimecode, SIGNAL(clicked()), | ||||
this, SLOT(sendSystemTimeAndTimecode())); | ||||
connect(this->UI->button_sendArbitraryTimeAndTimecode, SIGNAL(clicked()), | ||||
this, SLOT(sendArbitraryTimeAndTimecode())); | ||||
connect(this->time, SIGNAL(timeout()), this, SLOT(periodicalTimecodeTimeout())); | ||||
this->setLayout(UI->layout()); | ||||
} | ||||
MainWindow::~MainWindow() | ||||
{ | ||||
} | ||||
void MainWindow::sendOneTimecode() | ||||
{ | ||||
unsigned int result; | ||||
U32 timecodeReg, val; | ||||
result = testBrick(); | ||||
if (result != 0) | ||||
emit sendMessage("in sendOneTimeCode *** testBrick returned " + QString::number(result) ); | ||||
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::sendTimecodesPeriodicallyPC() | ||||
{ | ||||
if(time->isActive()) | ||||
{ | ||||
time->stop(); | ||||
this->UI->startTimeButton->setText("start sending timecodes periodically [PC]"); | ||||
this->UI->button_sendSystemTimeAndTimecode->setEnabled( true ); | ||||
this->UI->button_sendArbitraryTimeAndTimecode->setEnabled( true ); | ||||
this->UI->startPeriodicalTimecode_StarDundee->setEnabled( true ); | ||||
} | ||||
else | ||||
{ | ||||
time->start(); | ||||
this->UI->startTimeButton->setText("stop sending timecodes periodically [PC]"); | ||||
this->UI->button_sendSystemTimeAndTimecode->setEnabled( false ); | ||||
this->UI->button_sendArbitraryTimeAndTimecode->setEnabled( false ); | ||||
this->UI->startPeriodicalTimecode_StarDundee->setEnabled( false ); | ||||
} | ||||
} | ||||
void MainWindow::sendTimecodesPeriodicallyStarDundee() | ||||
{ | ||||
U32 rtr_clk_freq; | ||||
unsigned int resultOpen; | ||||
if (flag_sendTimecodesPeriodicallyStarDundee == false) | ||||
{ | ||||
resultOpen = testBrick(); | ||||
if (resultOpen != 0) | ||||
emit sendMessage("in sendTimecodesPeriodicallyStarDundee *** testBrick returned " + QString::number(resultOpen) ); | ||||
rtr_clk_freq = USBSpaceWire_TC_GetClockFrequency(hDevice); | ||||
emit sendMessage("clock frequency = " + QString::number(rtr_clk_freq) ); | ||||
if (!USBSpaceWire_TC_SetAutoTickInFrequency(hDevice, rtr_clk_freq) ) | ||||
emit sendMessage("Could not set the tick-in frequency"); | ||||
if (!USBSpaceWire_TC_EnableAutoTickIn(hDevice, 1, 1)) | ||||
emit sendMessage("Could not enable auto tick-in"); | ||||
flag_sendTimecodesPeriodicallyStarDundee = true; | ||||
this->UI->startTimeButton->setEnabled( false ); | ||||
this->UI->button_sendSystemTimeAndTimecode->setEnabled( false ); | ||||
this->UI->button_sendArbitraryTimeAndTimecode->setEnabled( false ); | ||||
this->UI->startPeriodicalTimecode_StarDundee->setText("stop sending timecodes periodically [Star Dundee]"); | ||||
} | ||||
else | ||||
{ | ||||
resultOpen = testBrick(); | ||||
if (resultOpen != 0) | ||||
emit sendMessage("in sendTimecodesPeriodicallyStarDundee *** testBrick returned " + QString::number(resultOpen) ); | ||||
if (!USBSpaceWire_TC_EnableAutoTickIn(hDevice, 0, 0)) | ||||
emit sendMessage("Could not disable auto tick-in"); | ||||
flag_sendTimecodesPeriodicallyStarDundee = false; | ||||
this->UI->startTimeButton->setEnabled( true ); | ||||
this->UI->button_sendSystemTimeAndTimecode->setEnabled( true ); | ||||
this->UI->button_sendArbitraryTimeAndTimecode->setEnabled( true ); | ||||
this->UI->startPeriodicalTimecode_StarDundee->setText("start sending timecodes periodically [Star Dundee]"); | ||||
} | ||||
} | ||||
void MainWindow::periodicalTimecodeTimeout() | ||||
{ | ||||
sendOneTimecode(); | ||||
emit(systemTimeHasChanged(systemTime)); | ||||
if (flag_sendSystemTimePacket == true) | ||||
{ | ||||
systemTime = systemTime + 1; // this is the value of the next valid system time, will be displayed next timecode | ||||
flag_sendSystemTimePacket = false; | ||||
emit sendMessage("in periodicalTimecodeTimeout *** send in 700 ms: " + QString::number(systemTime, 16)); | ||||
QTimer::singleShot(700, this, SLOT(sendTimePacketTimeout())); | ||||
} | ||||
else if (flag_sendArbitraryTimePacket == true) | ||||
{ | ||||
systemTime = this->UI->arbitraryTime; // this is the value of the next valid system time, will be displayed next timecode | ||||
flag_sendArbitraryTimePacket = false; | ||||
emit sendMessage("in periodicalTimecodeTimeout *** send in 700 ms: " + QString::number(systemTime, 16)); | ||||
QTimer::singleShot(700, this, SLOT(sendTimePacketTimeout())); | ||||
} | ||||
else | ||||
{ | ||||
systemTime = systemTime + 1; | ||||
} | ||||
} | ||||
void MainWindow::sendTimePacketTimeout() | ||||
{ | ||||
sendUpdateTime( systemTime ); | ||||
} | ||||
void MainWindow::sendSystemTime() | ||||
{ | ||||
flag_sendSystemTimePacket = true; | ||||
} | ||||
void MainWindow::sendArbitraryTime() | ||||
{ | ||||
flag_sendArbitraryTimePacket = true; | ||||
} | ||||
void MainWindow::sendSystemTimeAndTimecode() | ||||
{ | ||||
sendUpdateTime( systemTime ); | ||||
QTimer::singleShot(300, this, SLOT(sendOneTimecode())); | ||||
} | ||||
void MainWindow::sendArbitraryTimeAndTimecode() | ||||
{ | ||||
sendUpdateTime( this->UI->arbitraryTime ); | ||||
QTimer::singleShot(300, this, SLOT(sendOneTimecode())); | ||||
} | ||||
unsigned int MainWindow::Open() | ||||
{ | ||||
U32 dwTickEnableStatus; | ||||
unsigned int status; | ||||
status = 0; // 0 is for a successful action | ||||
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(); | ||||
} | ||||
//*********************** | ||||
// TIMECODE CONFIGURATION | ||||
// (1) RESET | ||||
if (!USBSpaceWire_TC_Reset(hDevice)) | ||||
{ | ||||
emit sendMessage("ERR *** in Open *** Could not reset timecodes\n"); | ||||
} | ||||
// (2) 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"); | ||||
// (3) get the tick status | ||||
CFGSpaceWire_GetTickEnableStatus(hDevice, &dwTickEnableStatus); | ||||
emit sendMessage("OK *** in Open *** CFGSpaceWire_GetTickEnableStatus, code is " + QString::number(dwTickEnableStatus, 2)); | ||||
// (4) enable external timecode selection | ||||
if(!USBSpaceWire_TC_EnableExternalTimecodeSelection(hDevice,0)) | ||||
{ | ||||
emit sendMessage("ERR *** disable external timecode selection"); | ||||
} | ||||
return status; | ||||
} | ||||
unsigned int MainWindow::testBrick() | ||||
{ | ||||
unsigned int status; | ||||
status = 0; | ||||
if (hDevice==NULL) | ||||
status = Open(); // open the brick and configure it | ||||
if (status == 0) // is the brick running or not? | ||||
{ | ||||
if (!getLinkStatus(UI->linkNumber_SPINBOX->value())) | ||||
{ | ||||
emit sendMessage("ERR *** in testBrick *** stardundee brick not running"); | ||||
status = -1; | ||||
} | ||||
else | ||||
status = 0; | ||||
} | ||||
return status; | ||||
} | ||||
unsigned int MainWindow::getLinkStatus(unsigned char link) | ||||
{ | ||||
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; | ||||
// 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_TC_RPW_INTERNAL; | ||||
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; | ||||
} | ||||