stardundee.cpp
1118 lines
| 45.9 KiB
| text/x-c
|
CppLexer
/ rmapplugin / stardundee.cpp
r0 | #include "stardundee.h" | |||
r57 | #include <lppmonengine.h> | |||
|
r1 | #include <QTime> | ||
r57 | #include <QProgressBar> | |||
|
r1 | #include <math.h> | ||
r11 | #include "ccsds.h" | |||
r0 | ||||
StarDundee::StarDundee(QWidget *parent) : | ||||
QWidget(parent) | ||||
{ | ||||
r3 | // Packet receiver | |||
r10 | timer = new QTimer; | |||
r3 | rmapPacketSEMAPHORE = new QSemaphore; | |||
ccsdsPacketSEMAPHORE = new QSemaphore; | ||||
rmapPacket = (char*) malloc(RMAP_MAX_PACKET_LENGTH); | ||||
ccsdsPacket = (unsigned char*) malloc(CCSDS_MAX_PACKET_LENGTH); | ||||
spwPacket = (char*) malloc( qMax(RMAP_MAX_PACKET_LENGTH, CCSDS_MAX_PACKET_LENGTH) ); | ||||
r10 | starDundeeStatusQueryDialog = new QDialog; | |||
|
r1 | commandCode = invalid0; // initialization of the cmmand code for the RMAP transfers | ||
r11 | rmapTargetLogicalAddress = DEFAULT_TARGET; | |||
rmapSourceLogicalAddress = DEFAULT_SOURCE; | ||||
|
r1 | |||
r0 | connection_LAYOUT = new QGridLayout; | |||
usbDeviceNumber_LABEL = new QLabel(tr("USB device number: ")); | ||||
|
r1 | linkNumber_LABEL = new QLabel(tr("SpaceWire link number: ")); | ||
r62 | starDundeeStatusQueryDialogLabel = new QLabel(tr("SpaceWire links state")); | |||
statusLink1 = new QLabel(tr("Link 1 status code: -")); | ||||
statusLink2 = new QLabel(tr("Link 2 status code: -")); | ||||
r10 | ||||
//*** QPUSHBUTTON ***// | ||||
r62 | starDundeeStatusQueryContinueButton = new QPushButton(tr("Continue")); | |||
r10 | starDundeeStatusQueryRetryButton = new QPushButton(tr("Retry")); | |||
starDundeeStatusQueryAbortButton = new QPushButton(tr("Abort")); | ||||
r62 | starDundeeSendOneTimecode = new QPushButton(tr("send one timecode")); | |||
starDundeeSendOneTimePacketAndOneTimecode = new QPushButton(tr("send one update time\n+ one time code")); | ||||
starDundeeSendTimecodePeriodically = new QPushButton(tr("start timecodes at 1 Hz")); | ||||
starDundeeSendOneTimePacketAndTimecodePeriodically = new QPushButton(tr("send one update time\n+ timecodes at 1 Hz")); | ||||
arbitraryTime = new ArbitraryTime(1); // 1 is for the horizontal layout | ||||
arbitraryTimeToSend = 0x80000000; | ||||
paulCommonCRC = new PaulCommonCRC(); | ||||
flag_sendTimecodePeriodically = false; | ||||
starDundeeSendOneTimecode->setEnabled( false ); | ||||
starDundeeSendTimecodePeriodically->setEnabled( false ); | ||||
starDundeeSendOneTimePacketAndOneTimecode->setEnabled( false ); | ||||
starDundeeSendOneTimePacketAndTimecodePeriodically->setEnabled( false ); | ||||
r0 | ||||
usbDeviceNumber_SPINBOX = new QSpinBox; | ||||
usbDeviceNumber_SPINBOX->setRange(0,32); | ||||
usbDeviceNumber_SPINBOX->setValue(0); | ||||
|
r1 | linkNumber_SPINBOX = new QSpinBox; | ||
linkNumber_SPINBOX->setRange(1,2); | ||||
linkNumber_SPINBOX->setValue(1); | ||||
r0 | ||||
r10 | // STAR DUNDEE STATUS QUERY DIALOG | |||
starDundeeStatusQueryDialogLayout = new QGridLayout; | ||||
starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryDialogLabel, 0, 0, 1, 2); | ||||
r62 | starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryContinueButton, 1, 0, 0); | |||
starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryRetryButton, 1, 1, 0); | ||||
starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryAbortButton, 1, 2, 0); | ||||
starDundeeStatusQueryDialogLayout->addWidget(statusLink1, 2, 0, 0); | ||||
starDundeeStatusQueryDialogLayout->addWidget(statusLink2, 3, 0, 0); | ||||
r10 | starDundeeStatusQueryDialog->setLayout(starDundeeStatusQueryDialogLayout); | |||
|
r1 | connection_LAYOUT->addWidget(usbDeviceNumber_LABEL, 0, 0, 1, 1); | ||
connection_LAYOUT->addWidget(usbDeviceNumber_SPINBOX, 0, 1, 1, 1); | ||||
r3 | connection_LAYOUT->addWidget(linkNumber_LABEL, 1, 0, 1, 1); | |||
connection_LAYOUT->addWidget(linkNumber_SPINBOX, 1, 1, 1, 1); | ||||
r62 | connection_LAYOUT->addWidget(starDundeeSendOneTimecode, 2, 0, 1, 1); | |||
connection_LAYOUT->addWidget(starDundeeSendOneTimePacketAndOneTimecode, 2, 1, 1, 1); | ||||
connection_LAYOUT->addWidget(starDundeeSendTimecodePeriodically, 3, 0, 1, 1 ); | ||||
connection_LAYOUT->addWidget(starDundeeSendOneTimePacketAndTimecodePeriodically, 3, 1, 1, 1); | ||||
connection_LAYOUT->addWidget(arbitraryTime, 6, 0, 1, 2); | ||||
|
r1 | |||
r62 | connection_LAYOUT->setRowStretch(7, 1); | |||
|
r1 | connection_LAYOUT->setColumnStretch(2, 1); | ||
r0 | ||||
this->setLayout(connection_LAYOUT); | ||||
r62 | connect(starDundeeStatusQueryRetryButton, SIGNAL(clicked()), | |||
this, SLOT(reTestSPWLink())); | ||||
connect(starDundeeStatusQueryAbortButton, SIGNAL(clicked()), | ||||
starDundeeStatusQueryDialog, SLOT(reject())); | ||||
connect(starDundeeStatusQueryContinueButton, SIGNAL(clicked()), | ||||
starDundeeStatusQueryDialog, SLOT(accept())); | ||||
// TIMECODES | ||||
connect(this->starDundeeSendOneTimecode, SIGNAL(clicked()), | ||||
this, SLOT(sendOneTimecode())); | ||||
connect(this->starDundeeSendTimecodePeriodically, SIGNAL(clicked()), | ||||
this, SLOT(sendTimecodePeriodically())); | ||||
connect(this->starDundeeSendOneTimePacketAndOneTimecode, SIGNAL(clicked()), | ||||
this, SLOT(sendOneTimePacketAndOneTimecode())); | ||||
connect(this->starDundeeSendOneTimePacketAndTimecodePeriodically, SIGNAL(clicked()), | ||||
this, SLOT(sendOneTimePacketAndTimecodePeriodically())); | ||||
connect(this->arbitraryTime, SIGNAL(timeToSendChanged(long)), | ||||
this, SLOT(updateTimeToSend(long))); | ||||
r10 | ||||
connect(this->timer, SIGNAL(timeout()), this, SLOT(receivePollingLoop())); | ||||
r0 | } | |||
StarDundee::~StarDundee() | ||||
{ | ||||
r3 | free(rmapPacket); | |||
free(ccsdsPacket); | ||||
free(spwPacket); | ||||
r0 | USBSpaceWire_Close(hDevice); // Close the device | |||
} | ||||
r57 | bool StarDundee::Open() | |||
r0 | { | |||
|
r1 | int status; | ||
U32 statusControl; | ||||
r62 | unsigned int linkStatus1; | |||
unsigned int linkStatus2; | ||||
unsigned char linkNumber; | ||||
unsigned char deviceIsAnInterface; | ||||
|
r1 | |||
if (!USBSpaceWire_Open(&hDevice, usbDeviceNumber_SPINBOX->value())) // Open the USB device | ||||
r0 | { | |||
r11 | emit sendMessage("stardundee *** Open *** ERROR: USBSpaceWire_Open(&hDevice, 0))"); | |||
r57 | return false; | |||
r0 | } | |||
|
r1 | emit sendMessage("stardundee *** Open *** USBSpaceWire_Open successful, device number: " | ||
+ QString::number(usbDeviceNumber_SPINBOX->value())); | ||||
USBSpaceWire_EnableNetworkMode(hDevice, 0); // deactivate the network mode | ||||
r11 | CFGSpaceWire_EnableRMAP(1); // Enable the use of RMAP for the StarDundee brick configuration | |||
|
r1 | CFGSpaceWire_SetRMAPDestinationKey(0x20); // Set the destination key expected by STAR-Dundee devices | ||
// Set the path and return path to the device | ||||
r62 | // This affects just the operations performed by the Configuration Library and does not affect the packets | |||
// sent and received using the driver API. | ||||
|
r1 | CFGSpaceWire_StackClear(); | ||
CFGSpaceWire_AddrStackPush(0); | ||||
CFGSpaceWire_AddrStackPush(254); | ||||
CFGSpaceWire_RetAddrStackPush(254); | ||||
// set the base transmit rate to 100 MHz | ||||
status = CFGSpaceWire_SetBrickBaseTransmitRate( hDevice, CFG_BRK_CLK_100_MHZ, CFG_BRK_DVDR_1, 0xff); | ||||
if (status != CFG_TRANSFER_SUCCESS) | ||||
{ | ||||
emit sendMessage("ERROR CFGSpaceWire_SetBrickBaseTransmitRate"); | ||||
} | ||||
else emit sendMessage("OK CFGSpaceWire_SetBrickBaseTransmitRate, base rate = 100 MHz"); | ||||
r62 | ||||
//********************* | ||||
// LINK 1 CONFIGURATION | ||||
linkNumber = 1; | ||||
if (CFGSpaceWire_GetLinkStatusControl(hDevice, linkNumber, &statusControl) != CFG_TRANSFER_SUCCESS) | ||||
emit sendMessage("Could not read link status control for link " + QString::number(linkNumber)); | ||||
|
r1 | else | ||
{ | ||||
r62 | emit sendMessage("OK CFGSpaceWire_GetLinkStatusControl of link " + QString::number(linkNumber)); | |||
|
r1 | |||
// Set the link status control register properties | ||||
CFGSpaceWire_LSEnableAutoStart(&statusControl, 1); | ||||
CFGSpaceWire_LSEnableStart(&statusControl, 1); | ||||
CFGSpaceWire_LSEnableDisabled(&statusControl, 0); | ||||
CFGSpaceWire_LSEnableTristate(&statusControl, 0); | ||||
CFGSpaceWire_LSSetOperatingSpeed(&statusControl, 9); // sets the link speed to ( 100 MHz / (9+1) ) = 10 MHz | ||||
// Set the link status control register | ||||
r62 | if (CFGSpaceWire_SetLinkStatusControl(hDevice, linkNumber, statusControl) != CFG_TRANSFER_SUCCESS) | |||
emit sendMessage("Could not set the link status control for link " + QString::number(linkNumber)); | ||||
else | ||||
emit sendMessage("link status control for link " + QString::number(0x01) + " is set"); | ||||
|
r1 | } | ||
r62 | //********************* | |||
// LINK 2 CONFIGURATION | ||||
linkNumber = 2; | ||||
if (CFGSpaceWire_GetLinkStatusControl(hDevice, linkNumber, &statusControl) != CFG_TRANSFER_SUCCESS) | ||||
emit sendMessage("Could not read link status control for link " + QString::number(linkNumber)); | ||||
r11 | else | |||
{ | ||||
r62 | emit sendMessage("OK CFGSpaceWire_GetLinkStatusControl of link " + QString::number(linkNumber)); | |||
// Set the link status control register properties | ||||
CFGSpaceWire_LSEnableAutoStart(&statusControl, 1); | ||||
CFGSpaceWire_LSEnableStart(&statusControl, 1); | ||||
CFGSpaceWire_LSEnableDisabled(&statusControl, 0); | ||||
CFGSpaceWire_LSEnableTristate(&statusControl, 0); | ||||
CFGSpaceWire_LSSetOperatingSpeed(&statusControl, 9); // sets the link speed to ( 100 MHz / (9+1) ) = 10 MHz | ||||
// Set the link status control register | ||||
if (CFGSpaceWire_SetLinkStatusControl(hDevice, linkNumber, statusControl) != CFG_TRANSFER_SUCCESS) | ||||
emit sendMessage("Could not set the link status control for link " + QString::number(linkNumber)); | ||||
else | ||||
emit sendMessage("link status control for link " + QString::number(linkNumber) + " is set"); | ||||
r11 | } | |||
|
r1 | |||
r62 | //******************************* | |||
// SET THE DEVICE AS AN INTERFACE | ||||
deviceIsAnInterface = 1; | ||||
if (CFGSpaceWire_SetAsInterface(hDevice, deviceIsAnInterface, 0) != CFG_TRANSFER_SUCCESS) | ||||
emit sendMessage("Could not set the device to be an interface"); | ||||
else | ||||
emit sendMessage("Device is an interface: " + QString::number(deviceIsAnInterface) + " (1 => true, 0 => false)"); | ||||
|
r1 | |||
r62 | // setRoutingTableEntry(0xfe, 0x02); // [0010] => connect LFR on the [Link 1] port | |||
// setRoutingTableEntry(0xfd, 0x04); // [0100] => connect TIMEGEN on the [Link 2] port | ||||
// GetRoutingTableEntry(0xfe); | ||||
// GetRoutingTableEntry(0xfd); | ||||
// GetRoutingTableEntry(0x01); | ||||
USBSpaceWire_RegisterReceiveOnAllPorts(hDevice); // Register to receive on port 1 only | ||||
// USBSpaceWire_RegisterReceiveOnPort(hDevice, 0x01); // Register to receive on port 1 only | ||||
// USBSpaceWire_RegisterReceiveOnPort(hDevice, 0xfe); // Register to receive on port 254 only | ||||
r3 | USBSpaceWire_ClearEndpoints(hDevice); // clear the USB endpoints | |||
|
r1 | |||
r11 | emit sendMessage("The driver's current send buffer size is " + QString::number(USBSpaceWire_GetDriverSendBufferSize(hDevice)) + " bytes"); | |||
emit sendMessage("The driver's current read buffer size is " + QString::number(USBSpaceWire_GetDriverReadBufferSize(hDevice)) + " bytes"); | ||||
emit sendMessage("USBSpaceWire_IsReadThrottling is " + QString::number(USBSpaceWire_IsReadThrottling(hDevice))); | ||||
r3 | // initialize SPW packet semaphores | |||
while (rmapPacketSEMAPHORE->available()!=0) rmapPacketSEMAPHORE->acquire(); | ||||
while (ccsdsPacketSEMAPHORE->available()!=0) ccsdsPacketSEMAPHORE->acquire(); | ||||
|
r1 | |||
r62 | //************ | |||
// test Link 1 and Link 2 | ||||
linkStatus1 = getLinkStatus(0x01); | ||||
linkStatus2 = getLinkStatus(0x02); | ||||
if ((linkStatus1==1) || (linkStatus2==1)) | ||||
r10 | { | |||
r62 | // statusLink1->setText("Link 1 status code: " + QString::number(linkStatus1)); | |||
// statusLink2->setText("Link 2 status code: " + QString::number(linkStatus2)); | ||||
// starDundeeStatusQueryDialog->exec(); | ||||
r10 | emit isOpen(true); | |||
r59 | timer->start(1); // starts the periodical timer, period = 100ms | |||
r62 | initializeTimecodeGeneration(); | |||
r57 | return true; | |||
r10 | } | |||
else | ||||
{ | ||||
r62 | statusLink1->setText("Link 1 status code: " + QString::number(linkStatus1)); | |||
statusLink2->setText("Link 2 status code: " + QString::number(linkStatus2)); | ||||
r11 | starDundeeStatusQueryDialog->exec(); | |||
r57 | return false; | |||
r10 | } | |||
r0 | } | |||
r6 | void StarDundee::Close() | |||
r0 | { | |||
USBSpaceWire_Close(hDevice); // Close the device | ||||
|
r1 | emit sendMessage("stardundee *** Close *** USBSpaceWire_Close, device: " + QString::number(usbDeviceNumber_SPINBOX->value())); | ||
USBSpaceWire_UnregisterReceiveOnAllPorts(hDevice); // Stop receiving on all ports | ||||
r3 | emit isOpen(false); | |||
|
r1 | } | ||
r11 | unsigned char StarDundee::setRoutingTableEntry(int tableEntry, U32 dwOutputPorts) | |||
{ | ||||
U32 routingTableEntry; | ||||
// SET THE ROUTING TABLE ENTRY FOR LOGICAL ADDRESSING, TARGET entryNumber | ||||
if (CFGSpaceWire_ClearRoutingTableEntry(hDevice, tableEntry) != CFG_TRANSFER_SUCCESS) | ||||
{ | ||||
emit sendMessage("Could not clear routing table entry " + QString::number(tableEntry)); | ||||
} | ||||
// Build the routing table entry | ||||
CFGSpaceWire_RTBuildRoutingTableEntry(&routingTableEntry, | ||||
dwOutputPorts, // route out of port dwOutputPorts | ||||
0, // header deletion disabled | ||||
0); // priority normal | ||||
// Set the routing table entry for logical address tableEntry | ||||
if (CFGSpaceWire_SetRoutingTableEntry(hDevice, tableEntry, routingTableEntry) != CFG_TRANSFER_SUCCESS) | ||||
{ | ||||
emit sendMessage("Could not set routing table entry [" + QString::number(tableEntry) + "]"); | ||||
} | ||||
else emit sendMessage("Routing table entry [" + QString::number(tableEntry) + "] set" ); | ||||
return 1; | ||||
} | ||||
unsigned int StarDundee::GetRoutingTableEntry(int tableEntry) | ||||
|
r1 | { | ||
U32 routingTableEntry, outputPorts; | ||||
char enabled, delHead, priority; | ||||
int portNum; | ||||
r11 | emit sendMessage("GetRoutingTableEntry [" + QString::number(tableEntry) + "]"); | |||
|
r1 | // Read the routing table entry | ||
if (CFGSpaceWire_GetRoutingTableEntry(hDevice, tableEntry, &routingTableEntry) != CFG_TRANSFER_SUCCESS) | ||||
{ | ||||
emit sendMessage("Could not read routing table entry [" + QString::number(tableEntry) + "]"); | ||||
} | ||||
else | ||||
{ | ||||
// Display the routing table entry properties | ||||
CFGSpaceWire_RTIsEnabled(routingTableEntry, &enabled); | ||||
CFGSpaceWire_RTIsDelHead(routingTableEntry, &delHead); | ||||
CFGSpaceWire_RTIsPriority(routingTableEntry, &priority); | ||||
CFGSpaceWire_RTGetOutputPorts(routingTableEntry, &outputPorts); | ||||
emit sendMessage("CFGSpaceWire_RTIsEnabled : " + QString::number(enabled)); | ||||
emit sendMessage("CFGSpaceWire_RTIsDelHead : " + QString::number(delHead)); | ||||
emit sendMessage("CFGSpaceWire_RTIsPriority : " + QString::number(priority)); | ||||
emit sendMessage("CFGSpaceWire_RTGetOutputPorts : "); | ||||
for (portNum = 0; portNum < 32; portNum++) | ||||
{ | ||||
if (outputPorts & (1 << portNum)) | ||||
{ | ||||
emit sendMessage(QString::number(portNum)); | ||||
} | ||||
} | ||||
} | ||||
return 1; | ||||
} | ||||
r3 | unsigned int StarDundee::Write(unsigned int *Value, unsigned int count, unsigned int address) | |||
|
r1 | { | ||
r3 | unsigned int remainingCount = count; | |||
unsigned int iOffset = 0; | ||||
QString console_message; | ||||
char* data; | ||||
if(rmapPacketSEMAPHORE->available()!=0) | ||||
{ | ||||
emit appendToLog("WARNING === in function WRITE of rmapplugin *** RMAP request already running, WRITE access stopped"); | ||||
return 1; | ||||
} | ||||
emit this->RMAP_write_reply_setText("reply to the write command required\nlast reply status: unavailable"); | ||||
data = (char*) malloc(READ_WRITE_MAX_COUNTS*4); | ||||
emit appendToLog(QString("*** START *** WRITE ")+ QString::number(count) + QString(" word(s) @0x")+ QString::number(address,16)); | ||||
r57 | ||||
QProgressBar* progress=NULL; | ||||
if (count > READ_WRITE_MAX_COUNTS) | ||||
{ | ||||
progress = lppmonEngine::getProgressBar("Reading on spw @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count); | ||||
} | ||||
r3 | ||||
while (remainingCount > READ_WRITE_MAX_COUNTS) | ||||
{ | ||||
r57 | // progress bar | |||
progress->setValue(count-remainingCount); | ||||
qApp->processEvents(); | ||||
r3 | for (int i = 0; i<READ_WRITE_MAX_COUNTS; i++) | |||
{ | ||||
data[i*4+3] = (char) ((unsigned int) Value[i+iOffset]); | ||||
data[i*4+2] = (char) ((unsigned int) Value[i+iOffset]>>8); | ||||
data[i*4+1] = (char) ((unsigned int) Value[i+iOffset]>>16); | ||||
data[i*4+0] = (char) ((unsigned int) Value[i+iOffset]>>24); | ||||
} | ||||
console_message.sprintf("remainingCount: %d => ", remainingCount); | ||||
emit appendToLog(console_message + QString("Write ")+ QString::number(READ_WRITE_MAX_COUNTS*4) + QString(" byte(s) @0x")+ QString::number(address,16)); | ||||
|
r1 | |||
r3 | if(WriteBLOCK(data, READ_WRITE_MAX_COUNTS*4, address)==0) | |||
{ | ||||
emit appendToLog("WARNING === in function WRITE of rmapplugin *** RMAP write command failed"); | ||||
return 1; | ||||
} | ||||
remainingCount = remainingCount - READ_WRITE_MAX_COUNTS; | ||||
address = address + READ_WRITE_MAX_COUNTS * 4; | ||||
iOffset = iOffset + READ_WRITE_MAX_COUNTS; | ||||
} | ||||
if (remainingCount > 0) | ||||
|
r1 | { | ||
r3 | for (unsigned int i = 0; i<remainingCount; i++) | |||
{ | ||||
data[i*4+3] = (char) ((unsigned int) Value[i+iOffset]); | ||||
data[i*4+2] = (char) ((unsigned int) Value[i+iOffset]>>8); | ||||
data[i*4+1] = (char) ((unsigned int) Value[i+iOffset]>>16); | ||||
data[i*4+0] = (char) ((unsigned int) Value[i+iOffset]>>24); | ||||
} | ||||
console_message.sprintf("remainingCount: %d => ", remainingCount); | ||||
emit appendToLog(console_message + QString("Write ")+ QString::number(remainingCount*4) + QString(" byte(s) @0x")+ QString::number(address,16)); | ||||
|
r1 | |||
r3 | if (WriteBLOCK(data, remainingCount*4, address)==0) | |||
{ | ||||
emit appendToLog("WARNING === in function WRITE of rmapplugin *** RMAP write command failed"); | ||||
return 1; | ||||
} | ||||
} | ||||
|
r1 | |||
r57 | if (count > READ_WRITE_MAX_COUNTS) | |||
{ | ||||
lppmonEngine::deleteProgressBar(progress); | ||||
} | ||||
r3 | emit appendToLog(QString("*** STOP *** WRITE")); | |||
r57 | ||||
r3 | free(data); | |||
return count; | ||||
|
r1 | } | ||
r3 | unsigned int StarDundee::Read(unsigned int *Value, unsigned int count, unsigned int address) | |||
|
r1 | { | ||
r3 | unsigned int remainingCount = count; | |||
unsigned int iOffset = 0; | ||||
QString console_message; | ||||
if(rmapPacketSEMAPHORE->available()!=0) | ||||
{ | ||||
emit appendToLog("WARNING === in function READ of rmapplugin *** RMAP request already running, READ access stopped"); | ||||
return 1; | ||||
} | ||||
r53 | ||||
r3 | emit appendToLog(QString("*** START *** READ ")+ QString::number(count) + QString(" word(s) @0x")+ QString::number(address,16)); | |||
r57 | ||||
QProgressBar* progress=NULL; | ||||
if (count > READ_WRITE_MAX_COUNTS) | ||||
{ | ||||
progress = lppmonEngine::getProgressBar("Reading on spw @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count); | ||||
} | ||||
r3 | ||||
while (remainingCount > READ_WRITE_MAX_COUNTS) | ||||
{ | ||||
r57 | // progress bar | |||
progress->setValue(count-remainingCount); | ||||
qApp->processEvents(); | ||||
r3 | console_message.sprintf("remainingCount: %d => ", remainingCount); | |||
emit appendToLog(console_message + QString("Read ")+ QString::number(4*READ_WRITE_MAX_COUNTS) + QString(" byte(s) @0x")+ QString::number(address,16)); | ||||
if (this->ReadBLOCK(READ_WRITE_MAX_COUNTS*4, address)==0) | ||||
{ | ||||
emit appendToLog("WARNING === in function READ of rmapplugin *** RMAP packet not received"); | ||||
return 1; | ||||
} | ||||
for(int i=0;i<READ_WRITE_MAX_COUNTS;i++) | ||||
{ | ||||
Value[i+iOffset] = (unsigned char) rmapPacket[i*4+RMAP_READ_REPLY_HEADER_LENGTH]; | ||||
for(int j=1;j<4;j++) | ||||
{ | ||||
Value[i+iOffset]= ((unsigned char) (rmapPacket[i*4+j+RMAP_READ_REPLY_HEADER_LENGTH])) | ||||
+ Value[i+iOffset]*256; | ||||
} | ||||
} | ||||
remainingCount = remainingCount - READ_WRITE_MAX_COUNTS; | ||||
address = address + READ_WRITE_MAX_COUNTS * 4; | ||||
iOffset = iOffset + READ_WRITE_MAX_COUNTS; | ||||
this->acquireRMAPSemaphore(); | ||||
} | ||||
if (remainingCount > 0) | ||||
{ | ||||
console_message.sprintf("remainingCount: %d => ", remainingCount); | ||||
emit appendToLog(console_message + QString("Read ")+ QString::number(4*remainingCount) + QString(" byte(s) @0x")+ QString::number(address,16)); | ||||
if (this->ReadBLOCK(4*remainingCount, address)==0) | ||||
{ | ||||
emit appendToLog("WARNING === in function READ of rmapplugin *** RMAP packet not received"); | ||||
return 1; | ||||
} | ||||
for(unsigned int i=0;i<remainingCount;i++) | ||||
{ | ||||
Value[i+iOffset] = (unsigned char) rmapPacket[i*4+RMAP_READ_REPLY_HEADER_LENGTH]; | ||||
for(int j=1;j<4;j++) | ||||
{ | ||||
Value[i+iOffset]= ((unsigned char)(rmapPacket[i*4+j+RMAP_READ_REPLY_HEADER_LENGTH])) + Value[i+iOffset]*256; | ||||
} | ||||
} | ||||
this->acquireRMAPSemaphore(); | ||||
} | ||||
r57 | if (count > READ_WRITE_MAX_COUNTS) | |||
{ | ||||
lppmonEngine::deleteProgressBar(progress); | ||||
} | ||||
r3 | emit appendToLog(QString("*** STOP *** READ ")); | |||
return count; | ||||
|
r1 | } | ||
r3 | unsigned int StarDundee::WriteBLOCK(char *data, unsigned int nbBytes, unsigned int address) | |||
|
r1 | { | ||
RMAP *RMAPCommand; | ||||
r3 | char * packet; | |||
r11 | char* aux; | |||
r3 | unsigned char offset, headerSize, CRCSize; | |||
unsigned int totalSize; | ||||
int errorCode; | ||||
QString console_message; | ||||
|
r1 | |||
r3 | if (getLinkStatus(this->linkNumber_SPINBOX->value()) == 0) | |||
|
r1 | { | ||
r3 | this->Close(); | |||
return 1; | ||||
|
r1 | } | ||
r3 | RMAPCommand = new RMAP(this->commandCode, | |||
|
r1 | rmapTargetLogicalAddress, | ||
rmapSourceLogicalAddress, | ||||
address, | ||||
r3 | nbBytes, | |||
data); | ||||
|
r1 | headerSize = sizeof(RMAPCommand->RMAPHeader); | ||
CRCSize = 1; | ||||
//************************* | ||||
// BUILD THE PACKET TO SEND | ||||
r11 | totalSize = headerSize + nbBytes + CRCSize + PATH_ADDRESSING_OFFSET; | |||
r3 | packet = (char*) malloc( totalSize ); | |||
aux = (char*) ((void*) &RMAPCommand->RMAPHeader); | ||||
r62 | packet[0] = getPacketFirstByte(); // TO BE SUPPRESSED | |||
r11 | for(unsigned int i = 0; i<headerSize; i++) packet[i+PATH_ADDRESSING_OFFSET] = aux[i]; | |||
|
r1 | offset = headerSize; | ||
r3 | for(unsigned int i = 0; i<nbBytes; i++) | |||
|
r1 | { | ||
r11 | packet[i+offset+PATH_ADDRESSING_OFFSET] = data[i]; | |||
|
r1 | } | ||
r11 | packet[nbBytes+offset+PATH_ADDRESSING_OFFSET] = RMAPCommand->dataCRC; | |||
|
r1 | |||
r3 | //**************** | |||
|
r1 | // SEND THE PACKET | ||
result = USBSpaceWire_SendPacket(hDevice, | ||||
r3 | packet, | |||
|
r1 | totalSize, | ||
BWAIT_1, &pIdentifier); | ||||
if (result != TRANSFER_SUCCESS) | ||||
{ | ||||
emit sendMessage("ERROR *** WriteStarDundee when sending packet of size " | ||||
+ QString::number(totalSize) +", with code: " + QString::number(result)); | ||||
USBSpaceWire_FreeSend(hDevice, pIdentifier); | ||||
free(data); | ||||
return 1; | ||||
} | ||||
r53 | // else emit sendMessage("OK *** WriteStarDundee when sending packet of size " + QString::number(totalSize)); | |||
|
r1 | |||
//************** | ||||
// Free the send | ||||
USBSpaceWire_FreeSend(hDevice, pIdentifier); | ||||
r3 | free(packet); | |||
|
r1 | |||
if ( (commandCode == writeSingle_noVer_Rep) | (commandCode == writeInc_noVer_Rep) | | ||||
(commandCode == writeSingle_ver_rep) | (commandCode == writeInc_ver_rep) ) | ||||
{ | ||||
r3 | // WAIT FOR THE RMAP REPLY PACKET | |||
errorCode = this->receiveSPWPacket(1); | ||||
if (errorCode<=0) | ||||
|
r1 | { | ||
r3 | emit appendToLog("WARNING === in function WriteBLOCK of rmapplugin *** RMAP packet reception failed with code " + QString::number(errorCode)); | |||
return 0; | ||||
|
r1 | } | ||
r3 | if(rmapPacketSize != 8) | |||
|
r1 | { | ||
r3 | console_message.sprintf("WARNING === in function WRITE (with reply) of rmapplugin *** write reply format not compliant\n"); | |||
emit appendToLog(console_message); | ||||
return 0; | ||||
|
r1 | } | ||
r3 | switch (this->rmapPacket[3]) // byte 4 is the status byte in the reply | |||
|
r1 | { | ||
case 0: | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 0 Successfull"); | ||||
break; | ||||
case 1: | ||||
emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** General error code"); | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 1 General error code"); | ||||
break; | ||||
case 2: | ||||
emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** Unused RMAP packet type or command code"); | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 2 Unused RMAP packet type or command code"); | ||||
break; | ||||
case 3: | ||||
emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** Invalid key"); | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 3 Invalid key"); | ||||
break; | ||||
case 4: | ||||
emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** Invalid data CRC"); | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 4 Invalid data CRC"); | ||||
break; | ||||
case 5: | ||||
emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** Early EOP"); | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 5 Early EOP"); | ||||
break; | ||||
case 6: | ||||
emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** Too much data"); | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 6 Too much data"); | ||||
break; | ||||
case 7: | ||||
emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** EEP"); | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 7 EEP"); | ||||
break; | ||||
case 8: | ||||
emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** Reserved"); | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 8 Reserved"); | ||||
break; | ||||
case 9: | ||||
emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** Verify buffer overrun"); | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 9 Verify buffer overrun"); | ||||
break; | ||||
case 10: | ||||
emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** RMAP command not implemented or not authorised"); | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 10 RMAP command not implemented or not authorised"); | ||||
break; | ||||
case 11: | ||||
emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** RMW data length error"); | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 11 RMAP RMW data length error"); | ||||
break; | ||||
case 12: | ||||
emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** Invalid target logical address"); | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 12 Invalid target logical address"); | ||||
break; | ||||
} | ||||
r3 | this->acquireRMAPSemaphore(); | |||
|
r1 | } | ||
else | ||||
emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: unavailable"); | ||||
r3 | ||||
return nbBytes; | ||||
} | ||||
unsigned int StarDundee::ReadBLOCK(unsigned int nbBytes, unsigned int address) | ||||
{ | ||||
int errorCode; | ||||
RMAP *RMAPCommand; | ||||
r11 | char *packet; | |||
char *aux; | ||||
unsigned int dataLength = 0; | ||||
unsigned int totalSize = 0; | ||||
r3 | ||||
//********************** | ||||
// Check the link status | ||||
if ( getLinkStatus( this->linkNumber_SPINBOX->value() ) == 0 ) | ||||
{ | ||||
this->Close(); | ||||
emit appendToLog("WARNING === in function WriteSPW of StarDundee *** SPW link not running\n"); | ||||
return 0; | ||||
} | ||||
//********************** | ||||
// SEND THE READ COMMAND | ||||
if (nbBytes > 4) | ||||
{ | ||||
RMAPCommand = new RMAP(read_Inc, | ||||
rmapTargetLogicalAddress, | ||||
rmapSourceLogicalAddress, | ||||
address, | ||||
nbBytes, | ||||
NULL); | ||||
} | ||||
else | ||||
{ | ||||
RMAPCommand = new RMAP(read_Single, | ||||
rmapTargetLogicalAddress, | ||||
rmapSourceLogicalAddress, | ||||
address, | ||||
nbBytes, | ||||
NULL); | ||||
} | ||||
r11 | ||||
//************************* | ||||
// BUILD THE PACKET TO SEND | ||||
totalSize = sizeof(RMAPCommand->RMAPHeader) + PATH_ADDRESSING_OFFSET; | ||||
packet = (char*) malloc( totalSize ); | ||||
aux = (char*) ((void*) &RMAPCommand->RMAPHeader); | ||||
r62 | packet[0] = getPacketFirstByte(); // TO BE SUPPRESSED | |||
r11 | for (unsigned int i = 0; i<sizeof(RMAPCommand->RMAPHeader); i++) | |||
packet[i+PATH_ADDRESSING_OFFSET] = aux[i]; | ||||
//**************** | ||||
// SEND THE PACKET | ||||
r3 | result = USBSpaceWire_SendPacket(hDevice, | |||
r11 | packet, | |||
totalSize, | ||||
r3 | BWAIT_1, &pIdentifier); | |||
if (result != TRANSFER_SUCCESS) emit sendMessage("ERR *** ReadStarDundee *** ReadBLOCK *** sending the READ command "); | ||||
r11 | else | |||
{ | ||||
r53 | // emit sendMessage("OK *** ReadStarDundee *** ReadBLOCK *** sending the READ command"); | |||
// emit appendToLog("packet sent, B0 = " + QString::number(packet[0], 16) | ||||
// + " *** B1 = " + QString::number(packet[1], 16) | ||||
// + " *** B2 = " + QString::number(packet[2], 16) | ||||
// + " *** B3 = " + QString::number(packet[3], 16) | ||||
// + " *** B4 = " + QString::number(packet[4], 16) | ||||
// + " *** B5 = " + QString::number(packet[5], 16) | ||||
// ); | ||||
r11 | } | |||
//************** | ||||
// Free the send | ||||
USBSpaceWire_FreeSend(hDevice, pIdentifier); | ||||
free(packet); | ||||
r3 | ||||
//********************************* | ||||
// RECEIVE THE INCOMING RMAP PACKET | ||||
errorCode = this->receiveSPWPacket(1); // request ID 1 is for RMAP packet | ||||
if (errorCode<=0) | ||||
{ | ||||
emit appendToLog("WARNING === in function ReadBLOCK of StarDundee *** RMAP packet reception failed with code " + QString::number(errorCode)); | ||||
return 0; | ||||
} | ||||
dataLength = rmapPacketSize - RMAP_READ_REPLY_HEADER_LENGTH - RMAP_DATA_CRC_LENGTH; | ||||
if(dataLength != nbBytes) | ||||
{ | ||||
emit appendToLog("WARNING === in function READ of StarDundee *** number of data received (" | ||||
+QString::number(dataLength) | ||||
+") not equal to number of data requested (" | ||||
+QString::number(nbBytes) | ||||
+")"); | ||||
return 0; | ||||
} | ||||
return dataLength; | ||||
|
r1 | } | ||
r3 | unsigned int StarDundee::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 appendToLog("WARNING === in function WRITE of rmapplugin *** CCSDS packet size > 248 bytes\n"); | ||||
return 1; | ||||
} | ||||
emit appendToLog("*** START *** Send CCSDS packet of "+ QString::number(count) + " byte(s)"); | ||||
if ( getLinkStatus( this->linkNumber_SPINBOX->value() ) == 0 ) | ||||
{ | ||||
this->Close(); | ||||
emit appendToLog("WARNING === in function WriteSPW of StarDundee *** SPW link not running\n"); | ||||
return 1; | ||||
} | ||||
r11 | totalSize = count + 4 + PATH_ADDRESSING_OFFSET; // The StarDundee brick is in PATH addressing | |||
r3 | SPWData = (char*) malloc(totalSize); | |||
// SPW HEADER | ||||
r62 | SPWData[0] = getPacketFirstByte(); | |||
r11 | SPWData[0+PATH_ADDRESSING_OFFSET] = targetLogicalAddress; | |||
SPWData[1+PATH_ADDRESSING_OFFSET] = protocoleIdentifier; | ||||
SPWData[2+PATH_ADDRESSING_OFFSET] = reserved; | ||||
SPWData[3+PATH_ADDRESSING_OFFSET] = userApplication; | ||||
r3 | // CCSDS PACKET | |||
for (unsigned int i = 0; i<count; i++) | ||||
{ | ||||
r11 | SPWData[i+4+PATH_ADDRESSING_OFFSET] = Value[i]; | |||
r3 | } | |||
r11 | //**************** | |||
r3 | // 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; | ||||
} | ||||
r11 | else emit sendMessage("OK *** WriteSPW when sending packet of size " + QString::number(totalSize-1)); | |||
emit appendToLog("packet sent, B0 = " + QString::number(SPWData[0]) | ||||
+ " *** B1 = " + QString::number(SPWData[1]) | ||||
+ " *** B2 = " + QString::number(SPWData[2]) | ||||
+ " *** B3 = " + QString::number(SPWData[3]) | ||||
+ " *** B4 = " + QString::number(SPWData[4]) | ||||
+ " *** B5 = " + QString::number(SPWData[5]) | ||||
+ " *** B6 = " + QString::number(SPWData[6]) | ||||
+ " *** B7 = " + QString::number(SPWData[7]) | ||||
+ " *** B8 = " + QString::number(SPWData[8]) | ||||
+ " *** B9 = " + QString::number(SPWData[9]) | ||||
+ " *** B10 = " + QString::number(SPWData[10]) | ||||
+ " *** B11 = " + QString::number(SPWData[11]) | ||||
+ " *** B12 = " + QString::number(SPWData[12]) | ||||
); | ||||
r3 | ||||
//************** | ||||
// Free the send | ||||
USBSpaceWire_FreeSend(hDevice, pIdentifier); | ||||
free(SPWData); | ||||
emit appendToLog(QString("*** CCSDS packet sent")); | ||||
return 1; | ||||
} | ||||
unsigned int StarDundee::getLinkStatus(unsigned char link) | ||||
{ | ||||
U32 statusControl, errorStatus, portType; | ||||
U32 linkStatus, operatingSpeed, outputPortConnection; | ||||
char isLinkRunning, isAutoStart, isStart, isDisabled, isTristate; | ||||
|
r1 | |||
r3 | // Read the link status control register | |||
r62 | if (CFGSpaceWire_GetLinkStatusControl(hDevice, link, &statusControl) != CFG_TRANSFER_SUCCESS) | |||
r3 | { | |||
emit appendToLog("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; | ||||
} | ||||
r62 | void StarDundee::spaceWireLinkHasChanged(unsigned char spaceWireLink) | |||
{ | ||||
linkNumber_SPINBOX->setValue(spaceWireLink); | ||||
} | ||||
r11 | void StarDundee::receivePollingLoop() | |||
{ | ||||
timer->blockSignals(true); | ||||
if (USBSpaceWire_WaitOnReadPacketAvailable(hDevice, 0)) receiveSPWPacketLoop(0); | ||||
timer->blockSignals(false); | ||||
} | ||||
int StarDundee::receiveSPWPacketLoop(unsigned char requestID) | ||||
{ | ||||
int result = 0; | ||||
emit appendToLog("Number of packets dropped by the driver: " + | ||||
QString::number(USBSpaceWire_GetDriverDroppedPackets(hDevice))); | ||||
while (USBSpaceWire_WaitOnReadPacketAvailable(hDevice, 0)) | ||||
{ | ||||
result = receiveSPWPacket(requestID); | ||||
} | ||||
r17 | ||||
r11 | return result; | |||
} | ||||
r3 | int StarDundee::receiveSPWPacket(unsigned char requestID) // SLOT | |||
|
r1 | { | ||
r3 | unsigned int packetLength; | |||
unsigned int nbBytes; | ||||
unsigned nPacketNum; | ||||
USB_SPACEWIRE_PACKET_PROPERTIES properties; // The properties of the read | ||||
if (requestID==1) | ||||
{ | ||||
r10 | if (rmapPacketSEMAPHORE->available()) | |||
{ | ||||
return rmapPacketSize; | ||||
} | ||||
r3 | } | |||
//******************** | ||||
// TRY TO RECEIVE DATA | ||||
nbBytes = qMax(RMAP_MAX_PACKET_LENGTH, CCSDS_MAX_PACKET_LENGTH); // maximum size of the packet to receive | ||||
nPacketNum = 1; | ||||
r11 | result = USBSpaceWire_ReadPackets(hDevice, spwPacket, nbBytes, nPacketNum, BWAIT_1, &properties, &pIdentifierRead); | |||
r10 | if (result != TRANSFER_SUCCESS) | |||
{ | ||||
r62 | emit sendMessage("Error: Could not receive the packet, result = " + QString::number(result)); | |||
r13 | USBSpaceWire_FreeRead(hDevice, pIdentifierRead); // Free the read buffer | |||
r10 | return 0; | |||
} | ||||
r3 | else | |||
{ | ||||
r10 | packetLength = properties.len; | |||
r11 | if (properties.eop == SPACEWIRE_USB_NO_EOP) | |||
{ | ||||
emit appendToLog("No end of packet marker received"); | ||||
} | ||||
r53 | // else if (properties.eop == SPACEWIRE_USB_EOP) | |||
// { | ||||
// emit appendToLog("Normal end of packet marker received"); | ||||
// } | ||||
r11 | else if (properties.eop == SPACEWIRE_USB_EEP) | |||
{ | ||||
emit appendToLog("Error end of packet marker received"); | ||||
} | ||||
USBSpaceWire_FreeRead(hDevice, pIdentifierRead); // Free the read buffer | ||||
r3 | } | |||
switch(spwPacket[1]) // byte 1 is the protocole identifier in the SPW packet | ||||
{ | ||||
case 1: // 0x01 is the protocole identifier for RMAP packets | ||||
if (rmapPacketSEMAPHORE->available()!=0) return -3; // ERROR === previous RMAP packet not processed yet | ||||
for(unsigned int i=0; i<packetLength; i++) rmapPacket[i] = spwPacket[i]; | ||||
rmapPacketSize = packetLength; | ||||
rmapPacketSEMAPHORE->release(); | ||||
r53 | // emit appendToLog("RMAP packet of size " + QString::number(packetLength) + " received"); | |||
// emit appendToLog("packet received, B0 = " + QString::number(spwPacket[0], 16) | ||||
// + " *** B1 = " + QString::number(spwPacket[1], 16) | ||||
// + " *** B2 = " + QString::number(spwPacket[2], 16) | ||||
// + " *** B3 = " + QString::number(spwPacket[3], 16) | ||||
// + " *** B4 = " + QString::number(spwPacket[4], 16) | ||||
// + " *** B5 = " + QString::number(spwPacket[5], 16) | ||||
// ); | ||||
r3 | return packetLength; | |||
case 2: // 0x02 is the protocole identifier for CCSDS packets | ||||
r11 | if (ccsdsPacketSEMAPHORE->available()!=0) | |||
{ | ||||
emit sendMessage("in function [receiveSPWPacket] === ERROR === previous CCSDS packet not processed yet"); | ||||
return -4; // ERROR === previous CCSDS packet not processed yet | ||||
} | ||||
r3 | for(unsigned int i=0; i<packetLength; i++) ccsdsPacket[i] = spwPacket[i]; | |||
ccsdsPacketSize = packetLength; | ||||
r10 | emit appendToLog("CCSDS packet of size " + QString::number(packetLength) + " received"); | |||
r11 | emit appendToLog("packet received, byte0 " + QString::number(spwPacket[0], 16) | |||
+ " *** byte1 " + QString::number(spwPacket[1], 16) | ||||
+ " *** byte2 " + QString::number(spwPacket[2], 16) | ||||
+ " *** byte3 " + QString::number(spwPacket[3], 16)); | ||||
storeCCSDSPacket(ccsdsPacket, packetLength); | ||||
r3 | return packetLength; | |||
r11 | default: | |||
emit appendToLog("packet received, byte0 " + QString::number(spwPacket[0], 16) | ||||
+ " *** byte1 " + QString::number(spwPacket[1], 16) | ||||
+ " *** byte2 " + QString::number(spwPacket[2], 16) | ||||
+ " *** byte3 " + QString::number(spwPacket[3], 16)); | ||||
r12 | return 0; | |||
r3 | } | |||
return 0; | ||||
|
r1 | } | ||
r3 | ||||
r11 | unsigned int StarDundee::storeCCSDSPacket(unsigned char *ccsdsPacket, unsigned int size) | |||
r10 | { | |||
r17 | TMPacketToRead *generalPacket; | |||
r11 | ||||
r17 | generalPacket = new TMPacketToRead(ccsdsPacket, size); | |||
emit sendPacket(generalPacket); | ||||
r13 | ||||
r11 | return 1; | |||
r10 | } | |||
r3 | ||||
r11 | void StarDundee::reTestSPWLink() // SLOT | |||
r10 | { | |||
r11 | if (getLinkStatus(linkNumber_SPINBOX->value())) | |||
r10 | { | |||
r11 | emit isOpen(true); | |||
starDundeeStatusQueryDialog->accept(); | ||||
r10 | } | |||
} | ||||
r62 | ||||
unsigned char StarDundee::getPacketFirstByte() | ||||
{ | ||||
unsigned char firstByte; | ||||
firstByte = (unsigned char) this->linkNumber_SPINBOX->value(); | ||||
return firstByte; | ||||
} | ||||
//********** | ||||
// TIMECODES | ||||
void StarDundee::initializeTimecodeGeneration() | ||||
{ | ||||
U32 dwTickEnableStatus; | ||||
U32 rtr_clk_freq; | ||||
// (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"); | ||||
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"); | ||||
starDundeeSendOneTimecode->setEnabled( true ); | ||||
starDundeeSendTimecodePeriodically->setEnabled( true ); | ||||
starDundeeSendOneTimePacketAndOneTimecode->setEnabled( true ); | ||||
starDundeeSendOneTimePacketAndTimecodePeriodically->setEnabled( true ); | ||||
} | ||||
void StarDundee::sendOneTimecode() | ||||
{ | ||||
if(!USBSpaceWire_TC_PerformTickIn(hDevice, 0)) | ||||
emit sendMessage("ERR *** in sendOneTimecode *** perform TickIn"); | ||||
} | ||||
void StarDundee::sendOneTimePacketAndOneTimecode() | ||||
{ | ||||
sendUpdateTime( arbitraryTimeToSend ); | ||||
QTimer::singleShot(300, this, SLOT(sendOneTimecode())); | ||||
} | ||||
void StarDundee::sendOneTimePacketAndTimecodePeriodically() | ||||
{ | ||||
sendUpdateTime( arbitraryTimeToSend ); | ||||
starDundeeSendOneTimePacketAndTimecodePeriodically->setEnabled( false ); | ||||
QTimer::singleShot(300, this, SLOT(sendTimecodePeriodically())); | ||||
} | ||||
void StarDundee::sendTimecodePeriodically() | ||||
{ | ||||
if (flag_sendTimecodePeriodically == false) | ||||
{ | ||||
if (!USBSpaceWire_TC_EnableAutoTickIn(hDevice, 1, 1)) | ||||
emit sendMessage("Could not enable auto tick-in"); | ||||
flag_sendTimecodePeriodically = true; | ||||
this->starDundeeSendTimecodePeriodically->setText("stop timecodes at 1 Hz"); | ||||
r63 | starDundeeSendOneTimePacketAndTimecodePeriodically->setEnabled( false ); | |||
r62 | } | |||
else | ||||
{ | ||||
if (!USBSpaceWire_TC_EnableAutoTickIn(hDevice, 0, 0)) | ||||
emit sendMessage("Could not disable auto tick-in"); | ||||
flag_sendTimecodePeriodically = false; | ||||
this->starDundeeSendTimecodePeriodically->setText("start timecodes at 1 Hz"); | ||||
starDundeeSendOneTimePacketAndTimecodePeriodically->setEnabled( true ); | ||||
} | ||||
} | ||||
r63 | void StarDundee::startSendingTimecodePeriodically(unsigned char onOff) | |||
{ | ||||
if (onOff == 0) | ||||
{ | ||||
if (!USBSpaceWire_TC_EnableAutoTickIn(hDevice, 0, 0)) | ||||
emit sendMessage("Could not disable auto tick-in"); | ||||
flag_sendTimecodePeriodically = false; | ||||
this->starDundeeSendTimecodePeriodically->setText("start timecodes at 1 Hz"); | ||||
starDundeeSendOneTimePacketAndTimecodePeriodically->setEnabled( true ); | ||||
} | ||||
else | ||||
{ | ||||
if (!USBSpaceWire_TC_EnableAutoTickIn(hDevice, 1, 1)) | ||||
emit sendMessage("Could not enable auto tick-in"); | ||||
flag_sendTimecodePeriodically = true; | ||||
this->starDundeeSendTimecodePeriodically->setText("stop timecodes at 1 Hz"); | ||||
starDundeeSendOneTimePacketAndTimecodePeriodically->setEnabled( false ); | ||||
} | ||||
} | ||||
r62 | void StarDundee::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 | ||||
paulCommonCRC->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); | ||||
} | ||||
void StarDundee::updateTimeToSend(long timeToSend) | ||||
{ | ||||
arbitraryTimeToSend = timeToSend; | ||||
} | ||||