diff --git a/PAULs_LPPMON_PLUGINS.pro.user b/PAULs_LPPMON_PLUGINS.pro.user --- a/PAULs_LPPMON_PLUGINS.pro.user +++ b/PAULs_LPPMON_PLUGINS.pro.user @@ -1,6 +1,6 @@ - + ProjectExplorer.Project.ActiveTarget diff --git a/rmapplugin/rmapplugin.cpp b/rmapplugin/rmapplugin.cpp --- a/rmapplugin/rmapplugin.cpp +++ b/rmapplugin/rmapplugin.cpp @@ -47,8 +47,6 @@ rmapplugin::rmapplugin(QWidget *parent) connect(this->pyObject,SIGNAL(WriteSig(uint*,uint,uint)),this,SLOT(Write(uint*,uint,uint))); /*==============*/ - //connect(UI->rmapOpenCommunicationButton, SIGNAL(clicked()), this, SLOT(RMAP_CONNECT())); - //connect(UI->rmapCloseCommunicationButton, SIGNAL(clicked()), this, SLOT(RMAP_DISCONNECT())); connect(UI->rmapOpenCommunicationButton, SIGNAL(clicked()), this, SLOT(openBridge())); connect(UI->rmapCloseCommunicationButton, SIGNAL(clicked()), this, SLOT(closeBridge())); connect(RMAPSend_SOCKET, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(RMAPSendConnectionState(QAbstractSocket::SocketState))); @@ -76,7 +74,7 @@ rmapplugin::rmapplugin(QWidget *parent) connect(this, SIGNAL(gresbIsOpen(bool)), this, SLOT(gresbSelection(bool))); // Star Dundee - connect(this->UI->starDundee, SIGNAL(starDundeeIsOpen(bool)), this, SLOT(activatePluginViaStarDundee(bool))); + connect(this->UI->starDundee, SIGNAL(isOpen(bool)), this, SLOT(activatePluginViaStarDundee(bool))); connect(this->UI->starDundee, SIGNAL(RMAP_write_reply_setText(QString)), this, SLOT(RMAP_write_reply_setText(QString))); connect(this->UI->starDundee, SIGNAL(appendToLog(QString)), this, SLOT(appendToLog(QString))); @@ -99,7 +97,7 @@ unsigned int rmapplugin::Write(unsigned result = WriteGRESB(Value, count, address); break; case selectedBridgeIsStarDundee : - result = this->WriteStarDundee(Value, count, address); + result = UI->starDundee->Write(Value, count, address); break; default: result = 1; @@ -117,7 +115,7 @@ unsigned int rmapplugin::Read(unsigned i result = ReadGRESB(Value, count, address); break; case selectedBridgeIsStarDundee : - result = this->ReadStarDundee(Value, count, address); + result = UI->starDundee->Read(Value, count, address); break; default: result = 1; @@ -440,25 +438,29 @@ unsigned int rmapplugin::ReadBLOCK(unsig return dataLength; } -unsigned int rmapplugin::WriteStarDundee(unsigned int *Value, unsigned int count, unsigned int address) -{ - unsigned int result; - result = UI->starDundee->WriteStarDundee(Value, count, address); - return result; -} - -unsigned int rmapplugin::ReadStarDundee(unsigned int *Value, unsigned int count, unsigned int address) -{ - unsigned int result; - result = UI->starDundee->ReadStarDundee(Value, count, address); - return result; -} - //////// // SLOTS unsigned int rmapplugin::WriteSPW(char *Value, unsigned int count, char targetLogicalAddress, char userApplication) // SLOT { + unsigned int result; + switch(currentBridge) + { + case selectedBridgeIsGRESB : + result = WriteSPWGRESB(Value, count, targetLogicalAddress, userApplication); + break; + case selectedBridgeIsStarDundee : + result = UI->starDundee->WriteSPW(Value, count, targetLogicalAddress, userApplication); + break; + default: + result = 1; + break; + } + return result; +} + +unsigned int rmapplugin::WriteSPWGRESB(char *Value, unsigned int count, char targetLogicalAddress, char userApplication) +{ char protocoleIdentifier = 0x02; char reserved = 0x00; char gresbProtocole = 0x00; @@ -616,7 +618,7 @@ void rmapplugin::openBridge() RMAP_CONNECT(); break; case selectedBridgeIsStarDundee : - this->UI->starDundee->OpenStarDundee(); + this->UI->starDundee->Open(); break; default: break; @@ -631,7 +633,7 @@ void rmapplugin::closeBridge() RMAP_DISCONNECT(); break; case selectedBridgeIsStarDundee : - this->UI->starDundee->CloseStarDundee(); + this->UI->starDundee->Close(); break; default: break; @@ -796,16 +798,6 @@ int rmapplugin::GRESBStatusQuery() // SL return 0; } -void rmapplugin::displayOnConsole(QString message) -{ - this->UI->console->append(message); -} - -void rmapplugin::activatePluginViaStarDundee(bool flag) -{ - emit activateSig(flag); -} - void rmapplugin::RMAP_write_reply_setText(QString text) { this->UI->RMAP_write_reply->setText(text); @@ -927,10 +919,5 @@ void rmapplugin::gresbSelection(bool fla if (flag == false) UI->selection_GROUPBOX->setEnabled(true); } -// SLOTS -void rmapplugin::bridgeHasChanged(selectedBridge bridge) -{ - currentBridge = bridge; -} diff --git a/rmapplugin/rmapplugin.h b/rmapplugin/rmapplugin.h --- a/rmapplugin/rmapplugin.h +++ b/rmapplugin/rmapplugin.h @@ -54,8 +54,7 @@ public: int charTab_TO_int(char *charTab); unsigned int ReadGRESB(unsigned int *Value,unsigned int count,unsigned int address=0); unsigned int WriteGRESB(unsigned int *Value,unsigned int count,unsigned int address=0); - unsigned int ReadStarDundee(unsigned int *Value, unsigned int count, unsigned int address=0); - unsigned int WriteStarDundee(unsigned int *Value, unsigned int count, unsigned int address=0); + unsigned int WriteSPWGRESB(char *Value, unsigned int count, char targetLogicalAddress, char userApplication); public slots: unsigned int Write(unsigned int *Value,unsigned int count,unsigned int address=0); @@ -66,7 +65,7 @@ public slots: void send_TC_LFR_UPDATE_TIME(); void reset_TC_LFR_UPDATE_TIME(); int GRESBStatusQuery(); - void displayOnConsole(QString message); + void displayOnConsole(QString message) {this->UI->console->append(message);} // void RMAP_CONNECT(); void RMAP_DISCONNECT(); @@ -81,10 +80,10 @@ public slots: void GRESBConnectionState(QAbstractSocket::SocketState socketState); // void gresbSelection(bool flag); - void activatePluginViaStarDundee(bool flag); + void activatePluginViaStarDundee(bool flag) {emit activateSig(flag);} void RMAP_write_reply_setText(QString text); void appendToLog(QString text); - void bridgeHasChanged(selectedBridge bridge); + void bridgeHasChanged(selectedBridge bridge) {currentBridge = bridge;} signals: void ccsdsPacketReadyRead(char *ccsdsPacket, unsigned int size); diff --git a/rmapplugin/rmapplugin.pro b/rmapplugin/rmapplugin.pro --- a/rmapplugin/rmapplugin.pro +++ b/rmapplugin/rmapplugin.pro @@ -45,7 +45,8 @@ HEADERS += \ stardundee.h \ ../spw_usb_driver_v2.61/inc/spw_usb_api.h \ ../spw_usb_driver_v2.61/inc/spw_config_library.h \ - gresb.h + gresb.h \ + bridge.h SOURCES += \ @@ -59,7 +60,8 @@ SOURCES += \ spectralmatricesdmasimulator.cpp \ rmappluginpythonwrapper.cpp \ stardundee.cpp \ - gresb.cpp + gresb.cpp \ + bridge.cpp diff --git a/rmapplugin/rmappluginui.cpp b/rmapplugin/rmappluginui.cpp --- a/rmapplugin/rmappluginui.cpp +++ b/rmapplugin/rmappluginui.cpp @@ -47,21 +47,21 @@ rmapPluginUI::rmapPluginUI(QWidget *pare generalParameters_GROUPBOX = new QGroupBox(tr("General parameters")); //*** QLABEL ***// - gresbBridgeIPLabel = new QLabel(tr("GRESB Bridge IP: ")); - gresbVirtualLinkLabel = new QLabel(tr("GRESB Virtual Link: ")); - spwLinkLabel = new QLabel(tr("GRESB SPW Link: ")); + gresbBridgeIPLabel = new QLabel(tr("Bridge IP: ")); + gresbVirtualLinkLabel = new QLabel(tr("Virtual Link: ")); + spwLinkLabel = new QLabel(tr("SPW Link: ")); rmapSourceLogicalAddressLabel = new QLabel(tr("RMAP Source Logical Address: ")); rmapTargetLogicalAddressLabel = new QLabel(tr("RMAP Target Logical Address: ")); rmapSendStateLabel = new QLabel(tr("RMAP Send Socket State: waiting for connection")); rmapReceiveStateLabel = new QLabel(tr("RMAP Receive Socket State: waiting for connection")); logFileName = new QLabel; - gresbStatusQueryLabel = new QLabel(tr("GRESB status query socket (port 3010): waiting for connection")); + gresbStatusQueryLabel = new QLabel(tr("Status query socket (port 3010): waiting for connection")); gresbStatusQueryDialogLabel = new QLabel(tr("sockets opened but SpaceWire link not running")); sendCCSDSCommandLabel = new QLabel(tr("Address of the target")); //*** QPUSHBUTTON ***// - rmapOpenCommunicationButton = new QPushButton(tr("Open RMAP Communication")); - rmapCloseCommunicationButton = new QPushButton(tr("Close RMAP Communication")); + rmapOpenCommunicationButton = new QPushButton(tr("Open selected bridge")); + rmapCloseCommunicationButton = new QPushButton(tr("Close selected bridge")); rmapOpenCommunicationButton->setEnabled(false); rmapCloseCommunicationButton->setEnabled(false); logFileChooseButton = new QPushButton(tr("Choose file")); @@ -86,7 +86,6 @@ rmapPluginUI::rmapPluginUI(QWidget *pare rmapSourceLogicalAddressSpinBox->setRange(0, 255); rmapSourceLogicalAddressSpinBox->setValue(33); rmapTargetLogicalAddressSpinBox->setRange(0, 255); - rmapTargetLogicalAddressSpinBox->setValue(254); spwLinkSpinBox->setRange(0, 2); spwLinkSpinBox->setValue(0); CCSDSTargetLogicalAddressSpinBox->setRange(0,255); @@ -130,11 +129,11 @@ rmapPluginUI::rmapPluginUI(QWidget *pare generalParameters_LAYOUT->addWidget(logFileChooseButton, 0, 1, 1, 1); generalParameters_LAYOUT->addWidget(rmapTargetLogicalAddressLabel, 1, 0, 0); generalParameters_LAYOUT->addWidget(rmapTargetLogicalAddressSpinBox, 1, 1, 0); - generalParameters_LAYOUT->addWidget(rmapOpenCommunicationButton, 2, 0, 1, 2); - generalParameters_LAYOUT->addWidget(rmapCloseCommunicationButton, 3, 0, 1, 2); - generalParameters_LAYOUT->addWidget(RMAP_write_verify, 4, 0, 1, 2); - generalParameters_LAYOUT->addWidget(RMAP_write_reply, 5, 0, 1, 2); - generalParameters_LAYOUT->setRowStretch(6, 1); + generalParameters_LAYOUT->addWidget(rmapOpenCommunicationButton, 2, 0, 1, 1); + generalParameters_LAYOUT->addWidget(rmapCloseCommunicationButton, 2, 1, 1, 1); + generalParameters_LAYOUT->addWidget(RMAP_write_verify, 3, 0, 1, 2); + generalParameters_LAYOUT->addWidget(RMAP_write_reply, 4, 0, 1, 2); + generalParameters_LAYOUT->setRowStretch(5, 1); generalParameters_LAYOUT->setColumnStretch(2, 1); gresb_GROUPBOX->setLayout(connectionLayout); @@ -188,14 +187,16 @@ rmapPluginUI::rmapPluginUI(QWidget *pare connect(this->clearConsoleButton, SIGNAL(clicked()), this->console, SLOT(clear())); connect(this->selectGRESB_BUTTON, SIGNAL(clicked()), this, SLOT(selectionBetweenGresbAndStarDundee())); connect(this->selectStarDundee_BUTTON, SIGNAL(clicked()), this, SLOT(selectionBetweenGresbAndStarDundee())); - connect(this->starDundee, SIGNAL(starDundeeIsOpen(bool)), this, SLOT(starDundeeIsOpen(bool))); + connect(this->starDundee, SIGNAL(isOpen(bool)), this, SLOT(isOpen(bool))); + connect(this->rmapTargetLogicalAddressSpinBox, SIGNAL(valueChanged(int)), this->starDundee, SLOT(targetHasChanged(int))); // command code connect(this->RMAP_write_reply, SIGNAL(clicked()), this, SLOT(getCommandCode())); connect(this->RMAP_write_verify, SIGNAL(clicked()), this, SLOT(getCommandCode())); - connect(this, SIGNAL(commandCodeHasChanged(RMAP_command_codes)), this->starDundee, SLOT(updateCommandCode(RMAP_command_codes))); + connect(this, SIGNAL(commandCodeHasChanged(RMAP_command_codes)), this->starDundee, SLOT(commandCodeHasChanged(RMAP_command_codes))); getCommandCode(); // init the command code value + rmapTargetLogicalAddressSpinBox->setValue(254); } void rmapPluginUI::connectPort() @@ -304,7 +305,7 @@ void rmapPluginUI::selectionBetweenGresb } } -void rmapPluginUI::starDundeeIsOpen(bool flag) +void rmapPluginUI::isOpen(bool flag) { if (flag == true) { diff --git a/rmapplugin/rmappluginui.h b/rmapplugin/rmappluginui.h --- a/rmapplugin/rmappluginui.h +++ b/rmapplugin/rmappluginui.h @@ -118,13 +118,14 @@ public slots: private slots: void selectionBetweenGresbAndStarDundee(); - void starDundeeIsOpen(bool flag); + void isOpen(bool flag); signals: void connectPortsig(QString PortName,int baudrate); void setLogFileName(QString FileName); void commandCodeHasChanged(RMAP_command_codes commandCode); void bridgeHasChanged(selectedBridge bridge); + void targetHasChanged(unsigned char target); private: QLabel *gresbBridgeIPLabel; diff --git a/rmapplugin/stardundee.cpp b/rmapplugin/stardundee.cpp --- a/rmapplugin/stardundee.cpp +++ b/rmapplugin/stardundee.cpp @@ -5,21 +5,20 @@ StarDundee::StarDundee(QWidget *parent) : QWidget(parent) { + // Packet receiver + 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) ); + commandCode = invalid0; // initialization of the cmmand code for the RMAP transfers - rmapPacket = (unsigned char*) malloc(RMAP_MAX_PACKET_LENGTH); - rmapTargetLogicalAddress = 0xfe; rmapSourceLogicalAddress = 0x20; connection_LAYOUT = new QGridLayout; - sendPacket_BUTTON = new QPushButton(tr("Send a packet")); - sendRMAPPacket_BUTTON = new QPushButton(tr("Write RMAP packet to the specified target")); - readRMAPPacket_BUTTON = new QPushButton(tr("Read RMAP packet from the specified target")); - getRoutingTableEntry_BUTTON = new QPushButton(tr("Get routing table entry (target logical address)")); - usbDeviceNumber_LABEL = new QLabel(tr("USB device number: ")); linkNumber_LABEL = new QLabel(tr("SpaceWire link number: ")); - routingTableEntry_LABEL = new QLabel(tr("Target logical address: ")); sourceLogicalAddress_LABEL = new QLabel(tr("Source logical address: ")); usbDeviceNumber_SPINBOX = new QSpinBox; @@ -28,48 +27,34 @@ StarDundee::StarDundee(QWidget *parent) linkNumber_SPINBOX = new QSpinBox; linkNumber_SPINBOX->setRange(1,2); linkNumber_SPINBOX->setValue(1); - routingTableEntry_SPINBOX = new QSpinBox; - routingTableEntry_SPINBOX->setRange(0, 254); - routingTableEntry_SPINBOX->setValue(254); sourceLogicalAddress_SPINBOX = new QSpinBox; sourceLogicalAddress_SPINBOX->setRange(0,254); sourceLogicalAddress_SPINBOX->setValue(32); - sendPacket_BUTTON->setEnabled(false); - sendRMAPPacket_BUTTON->setEnabled(false); - readRMAPPacket_BUTTON->setEnabled(false); - getRoutingTableEntry_BUTTON->setEnabled(false); - connection_LAYOUT->addWidget(usbDeviceNumber_LABEL, 0, 0, 1, 1); connection_LAYOUT->addWidget(usbDeviceNumber_SPINBOX, 0, 1, 1, 1); - connection_LAYOUT->addWidget(sendPacket_BUTTON, 1, 0, 1, 2); - connection_LAYOUT->addWidget(linkNumber_LABEL, 2, 0, 1, 1); - connection_LAYOUT->addWidget(linkNumber_SPINBOX, 2, 1, 1, 1); - connection_LAYOUT->addWidget(sourceLogicalAddress_LABEL, 3, 0, 1, 1); - connection_LAYOUT->addWidget(sourceLogicalAddress_SPINBOX, 3, 1, 1, 1); - connection_LAYOUT->addWidget(routingTableEntry_LABEL, 4, 0, 1, 1); - connection_LAYOUT->addWidget(routingTableEntry_SPINBOX, 4, 1, 1, 1); - connection_LAYOUT->addWidget(sendRMAPPacket_BUTTON, 5, 0, 1, 2); - connection_LAYOUT->addWidget(readRMAPPacket_BUTTON, 6, 0, 1, 2); - connection_LAYOUT->addWidget(getRoutingTableEntry_BUTTON, 7, 0, 1, 2); + connection_LAYOUT->addWidget(linkNumber_LABEL, 1, 0, 1, 1); + connection_LAYOUT->addWidget(linkNumber_SPINBOX, 1, 1, 1, 1); + connection_LAYOUT->addWidget(sourceLogicalAddress_LABEL, 2, 0, 1, 1); + connection_LAYOUT->addWidget(sourceLogicalAddress_SPINBOX, 2, 1, 1, 1); - connection_LAYOUT->setRowStretch(8, 1); + connection_LAYOUT->setRowStretch(3, 1); connection_LAYOUT->setColumnStretch(2, 1); this->setLayout(connection_LAYOUT); - connect(this->sendPacket_BUTTON, SIGNAL(clicked()), this, SLOT(SendPacket())); - connect(this->readRMAPPacket_BUTTON, SIGNAL(clicked()),this, SLOT(ReadRMAP())); - connect(this->sendRMAPPacket_BUTTON, SIGNAL(clicked()), this, SLOT(SendRMAP())); - connect(this->getRoutingTableEntry_BUTTON, SIGNAL(clicked()), this, SLOT(GetRoutingTableEntry())); + connect(this->sourceLogicalAddress_SPINBOX, SIGNAL(valueChanged(int)), this, SLOT(sourceHasChanged(int))); } StarDundee::~StarDundee() { + free(rmapPacket); + free(ccsdsPacket); + free(spwPacket); USBSpaceWire_Close(hDevice); // Close the device } -unsigned int StarDundee::OpenStarDundee() +unsigned int StarDundee::Open() { int status; U32 statusControl; @@ -126,7 +111,7 @@ unsigned int StarDundee::OpenStarDundee( } // SET THE ROUTING TABLE ENTRY FOR LOGICAL ADDRESSING, TARGET 254 <=> 0xfe - tableEntry = routingTableEntry_SPINBOX->value(); + tableEntry = rmapTargetLogicalAddress; if (CFGSpaceWire_ClearRoutingTableEntry(hDevice, tableEntry) != CFG_TRANSFER_SUCCESS) { emit sendMessage("Could not clear routing table entry " + QString::number(tableEntry)); @@ -166,32 +151,26 @@ unsigned int StarDundee::OpenStarDundee( emit sendMessage("The driver's current send buffer size is " + QString::number(USBSpaceWire_GetDriverSendBufferSize(hDevice)) + " bytes"); - sendPacket_BUTTON->setEnabled(true); - sendRMAPPacket_BUTTON->setEnabled(true); - readRMAPPacket_BUTTON->setEnabled(true); - getRoutingTableEntry_BUTTON->setEnabled(true); + USBSpaceWire_RegisterReceiveOnAllPorts(hDevice); // Register to receive on all ports + USBSpaceWire_ClearEndpoints(hDevice); // clear the USB endpoints - USBSpaceWire_RegisterReceiveOnAllPorts(hDevice); // Register to receive on all ports + // initialize SPW packet semaphores + while (rmapPacketSEMAPHORE->available()!=0) rmapPacketSEMAPHORE->acquire(); + while (ccsdsPacketSEMAPHORE->available()!=0) ccsdsPacketSEMAPHORE->acquire(); - emit starDundeeIsOpen(true); - - emit sendMessage("command code: " + QString::number(commandCode,16) ); + emit isOpen(true); return 1; } -unsigned int StarDundee::CloseStarDundee() +unsigned int StarDundee::Close() { USBSpaceWire_Close(hDevice); // Close the device emit sendMessage("stardundee *** Close *** USBSpaceWire_Close, device: " + QString::number(usbDeviceNumber_SPINBOX->value())); - sendPacket_BUTTON->setEnabled(false); - sendRMAPPacket_BUTTON->setEnabled(false); - readRMAPPacket_BUTTON->setEnabled(false); - getRoutingTableEntry_BUTTON->setEnabled(false); USBSpaceWire_UnregisterReceiveOnAllPorts(hDevice); // Stop receiving on all ports - emit starDundeeIsOpen(false); + emit isOpen(false); return 1; } @@ -203,7 +182,7 @@ unsigned int StarDundee::GetRoutingTable int portNum; int tableEntry; - tableEntry = routingTableEntry_SPINBOX->value(); + tableEntry = rmapTargetLogicalAddress; // Set the path and return path to the device CFGSpaceWire_StackClear(); @@ -239,177 +218,182 @@ unsigned int StarDundee::GetRoutingTable return 1; } -unsigned int StarDundee::SendPacket() +unsigned int StarDundee::Write(unsigned int *Value, unsigned int count, unsigned int address) { - U32 nBufferSize; // The amount of data, in bytes, to be transmitted. - char bWait; // If bWait is 0 then the transfer is started and the function returns immediately. - // If bWait is not 0 then the function will return only when the transfer is completed or an error is detected. + 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)); + + while (remainingCount > READ_WRITE_MAX_COUNTS) + { + for (int i = 0; i>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)); - nBufferSize = 10; - bWait = 1; - // Send the packet and wait on it completing - result = USBSpaceWire_SendPacket(hDevice, pBuffer, nBufferSize, bWait, &pIdentifier); - if (result != TRANSFER_SUCCESS) + 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) { - emit sendMessage("Error: Could not send the packet"); - } - else emit sendMessage("The packet has been successfully sent"); + for (unsigned int i = 0; i>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)); - // Free the send - USBSpaceWire_FreeSend(hDevice, pIdentifier); + if (WriteBLOCK(data, remainingCount*4, address)==0) + { + emit appendToLog("WARNING === in function WRITE of rmapplugin *** RMAP write command failed"); + return 1; + } + } - return 1; + emit appendToLog(QString("*** STOP *** WRITE")); + free(data); + return count; } -unsigned int StarDundee::SendRMAP() +unsigned int StarDundee::Read(unsigned int *Value, unsigned int count, unsigned int address) { - unsigned int Value[4]; - unsigned int count = 4; - unsigned int address = 0x40000000; - Value[0] = 0xabcd1234; - Value[1] = 0xbb; - Value[2] = 0xab; - Value[3] = 0xcd; - WriteStarDundee(Value, count, address); - return 1; + 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; + } + emit appendToLog(QString("*** START *** READ ")+ QString::number(count) + QString(" word(s) @0x")+ QString::number(address,16)); + + while (remainingCount > READ_WRITE_MAX_COUNTS) + { + 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;iacquireRMAPSemaphore(); + } + + 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;iacquireRMAPSemaphore(); + } + + emit appendToLog(QString("*** STOP *** READ ")); + return count; } -unsigned int StarDundee::ReadRMAP() -{ - unsigned int Value[100000]; - unsigned int count = 100000; - unsigned int address = 0x40000000; - unsigned int result; - result = ReadStarDundee(Value, count, address); - emit sendMessage("ReadRMAP, nbBytes: " + QString::number(result)); - emit sendMessage("Value[0]: " + QString::number(Value[0], 16)); - emit sendMessage("Value[1]: " + QString::number(Value[1], 16)); - emit sendMessage("Value[2]: " + QString::number(Value[2], 16)); - emit sendMessage("Value[3]: " + QString::number(Value[3], 16)); - return 1; -} - -unsigned int StarDundee::ReadStarDundee(unsigned int *Value, unsigned int count, unsigned int address) +unsigned int StarDundee::WriteBLOCK(char *data, unsigned int nbBytes, unsigned int address) { RMAP *RMAPCommand; - rmap_read_reply_PcktHdr_t rmapReplyHeader; - USB_SPACEWIRE_STATUS result; // The result of the receive operation - USB_SPACEWIRE_PACKET_PROPERTIES properties; // The properties of the read - unsigned int nbBytes; - unsigned char* packet; - U32 nPacketNum; - unsigned int offset; - unsigned int i; + char * packet; + unsigned char offset, headerSize, CRCSize; + char* aux; + unsigned int totalSize; + int errorCode; + QString console_message; - //********************** - // SEND THE READ COMMAND - nbBytes = 4 * count; - if (nbBytes > 4) + if (getLinkStatus(this->linkNumber_SPINBOX->value()) == 0) { - RMAPCommand = new RMAP(read_Inc, // build the command - rmapTargetLogicalAddress, - rmapSourceLogicalAddress, - address, - nbBytes, - NULL); - } - else - { - RMAPCommand = new RMAP(read_Single, // build the command - rmapTargetLogicalAddress, - rmapSourceLogicalAddress, - address, - nbBytes, - NULL); + this->Close(); + return 1; } - result = USBSpaceWire_SendPacket(hDevice, - (unsigned char*) ((void*) &RMAPCommand->RMAPHeader), - sizeof(RMAPCommand->RMAPHeader), - BWAIT_1, &pIdentifier); - if (result != TRANSFER_SUCCESS) emit sendMessage("ERROR *** ReadStarDundee when sending the READ command "); - else emit sendMessage("OK *** ReadStarDundee when sending the READ command"); - - //***************** - // RECEIVE THE DATA - nbBytes = sizeof(rmapReplyHeader) + 4 * count + 1; // 1 is for the data CRC - packet = (unsigned char *) malloc(nbBytes); - nPacketNum = 1; - result = USBSpaceWire_ReadPackets(hDevice, packet, nbBytes, nPacketNum, BWAIT_1, &properties, &pIdentifier); - if (result != TRANSFER_SUCCESS) emit sendMessage("Error: Could not receive the packet"); - else - { - emit sendMessage("A packet of length " + QString::number(properties.len) + " has been successfully received"); - offset = sizeof(rmapReplyHeader); - for(i=0; i>8); - dataCHAR[i*4+1] = (char) ((unsigned int) Value[i]>>16); - dataCHAR[i*4+0] = (char) ((unsigned int) Value[i]>>24); - } - - RMAPCommand = new RMAP(commandCode, + RMAPCommand = new RMAP(this->commandCode, rmapTargetLogicalAddress, rmapSourceLogicalAddress, address, - dataSize, - dataCHAR); - free(dataCHAR); + nbBytes, + data); headerSize = sizeof(RMAPCommand->RMAPHeader); CRCSize = 1; //************************* // BUILD THE PACKET TO SEND - totalSize = headerSize + dataSize + CRCSize; - data = (unsigned char*) malloc( totalSize ); - aux = (unsigned char*) ((void*) &RMAPCommand->RMAPHeader); - for(unsigned int i = 0; iRMAPHeader); + for(unsigned int i = 0; i>8); - data[offset+1] = (unsigned char) (Value[i]>>16); - data[offset] = (unsigned char) (Value[i]>>24); - offset = offset + 4; + packet[i+offset] = data[i]; } - data[offset] = RMAPCommand->dataCRC; + packet[nbBytes+offset] = RMAPCommand->dataCRC; - //************ + //**************** // SEND THE PACKET result = USBSpaceWire_SendPacket(hDevice, - data, + packet, totalSize, BWAIT_1, &pIdentifier); if (result != TRANSFER_SUCCESS) @@ -425,42 +409,25 @@ unsigned int StarDundee::WriteStarDundee //************** // Free the send USBSpaceWire_FreeSend(hDevice, pIdentifier); - free(data); + free(packet); if ( (commandCode == writeSingle_noVer_Rep) | (commandCode == writeInc_noVer_Rep) | (commandCode == writeSingle_ver_rep) | (commandCode == writeInc_ver_rep) ) { - //*********************** - // RECEIVE THE RMAP REPLY - totalSize = sizeof(rmapReplyHeader); - nPacketNum = 1; - result = USBSpaceWire_ReadPackets(hDevice, (char *) &rmapReplyHeader, totalSize, nPacketNum, BWAIT_1, &properties, &pIdentifier); - if (result != TRANSFER_SUCCESS) + // WAIT FOR THE RMAP REPLY PACKET + errorCode = this->receiveSPWPacket(1); + if (errorCode<=0) { - emit sendMessage("Error: Could not receive the RMAP reply"); - USBSpaceWire_FreeRead(hDevice, pIdentifier); // Free the receive - return 1; - } - else - { - emit sendMessage("An RMAP reply of length " + QString::number(properties.len) + " has been successfully received"); - USBSpaceWire_FreeRead(hDevice, pIdentifier); // Free the receive + emit appendToLog("WARNING === in function WriteBLOCK of rmapplugin *** RMAP packet reception failed with code " + QString::number(errorCode)); + return 0; } - if(properties.len != 8) + if(rmapPacketSize != 8) { - emit appendToLog("WARNING === in function WRITE (with reply) of rmapplugin *** write reply format not compliant\n"); - return 1; + console_message.sprintf("WARNING === in function WRITE (with reply) of rmapplugin *** write reply format not compliant\n"); + emit appendToLog(console_message); + return 0; } - emit sendMessage("data CRC " + QString::number(RMAPCommand->dataCRC, 16) ); - emit sendMessage("rmapReplyHeader " + QString::number(rmapReplyHeader.initiatorLogicalAddress, 16) ); - emit sendMessage("rmapReplyHeader " + QString::number(rmapReplyHeader.protocolIdentifier, 16) ); - emit sendMessage("rmapReplyHeader " + QString::number(rmapReplyHeader.instruction, 16) ); - emit sendMessage("rmapReplyHeader " + QString::number(rmapReplyHeader.status, 16) ); - emit sendMessage("rmapReplyHeader " + QString::number(rmapReplyHeader.targetLogicalAddress, 16) ); - emit sendMessage("rmapReplyHeader " + QString::number(rmapReplyHeader.transactionIdentifier1, 16) ); - emit sendMessage("rmapReplyHeader " + QString::number(rmapReplyHeader.transactionIdentifier2, 16) ); - emit sendMessage("rmapReplyHeader " + QString::number(rmapReplyHeader.headerCRC, 16) ); - switch (rmapReplyHeader.status) // byte 4 is the status byte in the reply + switch (this->rmapPacket[3]) // byte 4 is the status byte in the reply { case 0: emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 0 Successfull"); @@ -514,16 +481,233 @@ unsigned int StarDundee::WriteStarDundee emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: 12 Invalid target logical address"); break; } + this->acquireRMAPSemaphore(); } else emit RMAP_write_reply_setText("reply to the write command required\nlast reply status: unavailable"); - return count; + + return nbBytes; +} + +unsigned int StarDundee::ReadBLOCK(unsigned int nbBytes, unsigned int address) +{ + int errorCode; + RMAP *RMAPCommand; + unsigned int dataLength; + + //********************** + // 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); + } + result = USBSpaceWire_SendPacket(hDevice, + (unsigned char*) ((void*) &RMAPCommand->RMAPHeader), + sizeof(RMAPCommand->RMAPHeader), + BWAIT_1, &pIdentifier); + if (result != TRANSFER_SUCCESS) emit sendMessage("ERR *** ReadStarDundee *** ReadBLOCK *** sending the READ command "); + else emit sendMessage("OK *** ReadStarDundee *** ReadBLOCK *** sending the READ command"); + + //********************************* + // 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; } -//****** -// SLOTS +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; + } + + totalSize = count + 4; + SPWData = (char*) malloc(totalSize); + // SPW HEADER + SPWData[0] = targetLogicalAddress; + SPWData[1] = protocoleIdentifier; + SPWData[2] = reserved; + SPWData[3] = userApplication; + // CCSDS PACKET + for (unsigned int i = 0; iavailable()!=0) return -3; // ERROR === previous RMAP packet not processed yet + for(unsigned int i=0; irelease(); + emit sendMessage("RMAP packet of size " + QString::number(packetLength) + " received"); + return packetLength; + + case 2: // 0x02 is the protocole identifier for CCSDS packets + if (ccsdsPacketSEMAPHORE->available()!=0) return -4; // ERROR === previous CCSDS packet not processed yet + for(unsigned int i=0; irelease(); + emit(ccsdsPacketAvailable(ccsdsPacket, packetLength)); + return packetLength; + } + return 0; } + + diff --git a/rmapplugin/stardundee.h b/rmapplugin/stardundee.h --- a/rmapplugin/stardundee.h +++ b/rmapplugin/stardundee.h @@ -8,6 +8,7 @@ #include #include #include +#include #include "rmapoperations.h" #define BWAIT_0 0 @@ -19,54 +20,63 @@ class StarDundee : public QWidget public: explicit StarDundee(QWidget *parent = 0); ~StarDundee(); - unsigned int WriteStarDundee(unsigned int *Value,unsigned int count,unsigned int address=0); - unsigned int ReadStarDundee(unsigned int *Value,unsigned int count,unsigned int address=0); + unsigned int Write(unsigned int *Value,unsigned int count,unsigned int address=0); + unsigned int Read(unsigned int *Value,unsigned int count,unsigned int address=0); + unsigned int WriteStarDundee(unsigned int *Value, unsigned int count, unsigned int address); + unsigned int WriteSPW(char *Value, unsigned int count, char targetLogicalAddress, char userApplication); + unsigned int getLinkStatus(unsigned char link); signals: void sendMessage(QString message); - void starDundeeIsOpen(bool); + void isOpen(bool); void RMAP_write_reply_setText(QString); void appendToLog(QString); + void ccsdsPacketAvailable(unsigned char*, unsigned int); public slots: - unsigned int OpenStarDundee(); - unsigned int CloseStarDundee(); - unsigned int SendPacket(); - unsigned int SendRMAP(); - unsigned int ReadRMAP(); - unsigned int GetRoutingTableEntry(); - void updateCommandCode(RMAP_command_codes code); + unsigned int Open(); + unsigned int Close(); + int receiveSPWPacket(unsigned char requestID); + void commandCodeHasChanged(RMAP_command_codes code) {this->commandCode = code;} + void targetHasChanged(int target) {rmapTargetLogicalAddress = (unsigned char) target;} + void sourceHasChanged(int target) {rmapSourceLogicalAddress = (unsigned char) target;} private: - char rmapTargetLogicalAddress ; - char rmapSourceLogicalAddress ; + unsigned int GetRoutingTableEntry(); + unsigned int WriteBLOCK(char *data,unsigned int nbBytes,unsigned int address=0); + unsigned int ReadBLOCK(unsigned int nbBytes,unsigned int address=0); + void acquireRMAPSemaphore() {rmapPacketSEMAPHORE->acquire();} + void acquireCCSDSSemaphore() {ccsdsPacketSEMAPHORE->acquire();} - QPushButton *sendPacket_BUTTON; - QPushButton *sendRMAPPacket_BUTTON; - QPushButton *readRMAPPacket_BUTTON; - QPushButton *getRoutingTableEntry_BUTTON; + unsigned char rmapTargetLogicalAddress ; + unsigned char rmapSourceLogicalAddress ; + + RMAP_command_codes commandCode; QLabel *usbDeviceNumber_LABEL; QLabel *linkNumber_LABEL; - QLabel *routingTableEntry_LABEL; QLabel *sourceLogicalAddress_LABEL; QSpinBox *usbDeviceNumber_SPINBOX; QSpinBox *linkNumber_SPINBOX; - QSpinBox *routingTableEntry_SPINBOX; QSpinBox *sourceLogicalAddress_SPINBOX; QGridLayout *connection_LAYOUT; unsigned char pBuffer[10]; // Pointer to the start of the user buffer from which to transmit data - unsigned char* rmapPacket; // The buffer to receive RMAP READ packets USB_SPACEWIRE_ID pIdentifier; // A pointer to a variable which will be set to contain a unique identifier for the send - RMAP_command_codes commandCode; - star_device_handle hDevice; // Handle to the SpaceWire device USB_SPACEWIRE_STATUS result; // The result of the send operation + // Packet receiver + QSemaphore *rmapPacketSEMAPHORE; + QSemaphore *ccsdsPacketSEMAPHORE; + char* rmapPacket; // The buffer to receive RMAP READ packets + unsigned char *ccsdsPacket; + char *spwPacket; + unsigned int rmapPacketSize; + unsigned int ccsdsPacketSize; }; #endif // STARDUNDEE_H