##// END OF EJS Templates
Functions added to the plugin to get the number of CCSDS packets...
Functions added to the plugin to get the number of CCSDS packets transmitted (linked to the lfrcontrol plugin counter of TC transmitted, it is possible to flush the TC transmission before changing the spacewire link in use)

File last commit:

r40:cda6b4e8adc1 Patch 3 from Paul on spwplugin default
r40:cda6b4e8adc1 Patch 3 from Paul on spwplugin default
Show More
stardundeespw_usb.cpp
1074 lines | 46.7 KiB | text/x-c | CppLexer
/*------------------------------------------------------------------------------
-- This file is a part of the SocExplorer Software
-- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-------------------------------------------------------------------------------*/
/*-- Author : Alexis Jeandet
-- Mail : alexis.jeandet@member.fsf.org
----------------------------------------------------------------------------*/
#include "stardundeespw_usb.h"
#include <socexplorerengine.h>
#include <qhexedit.h>
QString dwLinkStatusQString[6] = {
"CFG_SPACEWIRE_ERROR_RESET",
"CFG_SPACEWIRE_ERROR_WAIT",
"CFG_SPACEWIRE_READY",
"CFG_SPACEWIRE_STARTED",
"CFG_SPACEWIRE_CONNECTING",
"CFG_SPACEWIRE_RUN"
};
stardundeeSPW_USB::stardundeeSPW_USB(socexplorerplugin *parent) :
abstractSpwBridge(parent)
{
Q_UNUSED(parent)
this->manager = new stardundeeSPW_USB_Manager(parent,this);
makeGUI(parent);
this->manager->start();
connect(this->manager,SIGNAL(emitPacket(char*,int)),this,SIGNAL(pushPacketOverTCP(char*,int)));
connect(this->manager, SIGNAL(bytesReceivedFromSpw(uint)), this, SIGNAL(BytesReceivedFromSpw(uint)));
connect(this->manager, SIGNAL(bytesTransmittedToSpw(uint)), this, SIGNAL(BytesTransmittedToSpw(uint)));
connect(this->manager, SIGNAL(ccsdsPacketTransmittedToSpw()), this, SIGNAL(CCSDSPacketTransmittedToSpw()));
}
stardundeeSPW_USB::~stardundeeSPW_USB()
{
this->manager->requestInterruption();
while(this->manager->isRunning());
}
void stardundeeSPW_USB::toggleBridgeConnection()
{
if(this->plugin->isConnected())
{
this->disconnectBridge();
}
else
{
this->connectBridge();
}
}
bool stardundeeSPW_USB::connectBridge()
{
if(this->manager->connectBridge())
{
this->timecodeFrequencyChanged( ((StarDundeeGUI*)this->p_GUI)->getTimecodeFrequency());
this->startSendingTimecodes( ((StarDundeeGUI*)this->p_GUI)->getStartSendingTimecodes());
((StarDundeeGUI*)this->p_GUI)->lock(true);
emit setConnected(true);
return true;
}
return false;
}
bool stardundeeSPW_USB::disconnectBridge()
{
if(this->manager->disconnectBridge())
{
((StarDundeeGUI*)this->p_GUI)->lock(false);
emit setConnected(false);
return true;
}
return false;
}
int stardundeeSPW_USB::pushRMAPPacket(char *packet, int size)
{
return this->manager->sendPacket(packet,size);
}
unsigned int stardundeeSPW_USB::Write(unsigned int *Value, unsigned int count, unsigned int address)
{
char writeBuffer[RMAP_WRITE_PACKET_MIN_SZ((RMAP_MAX_XFER_SIZE*4))+1];
char *RMAPAckBuff;
writeBuffer[0]=this->manager->linkNumber;//Link number
int transactionID = 0;
int written=0;
SocExplorerEngine::message(this->plugin,"Enter Write function",2);
QProgressBar* progress=NULL;
SocExplorerAutoProgressBar autopb;
if(count>RMAP_MAX_XFER_SIZE)
{
progress= SocExplorerEngine::getProgressBar("Writing on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
autopb.setProgressBar(progress);
}
//Quite stupide loop, I guess that I always get the number of byte I asked for!
while(count>=RMAP_MAX_XFER_SIZE)
{
for(int i=0;i<(RMAP_MAX_XFER_SIZE);i++)
{
writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+4] = (char)(((unsigned int)Value[i+written])&0xFF);
}
transactionID=manager->getRMAPtransactionID();
SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
RMAP_build_tx_request_header(
this->manager->destinationLogicalAddress,
this->manager->destinationKey,
this->manager->sourceLogicalAddress,
transactionID,
address+(written*4),
RMAP_MAX_XFER_SIZE*4,
writeBuffer+1);
manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(RMAP_MAX_XFER_SIZE*4)+1);
manager->getRMAPanswer(transactionID,&RMAPAckBuff);
free(RMAPAckBuff);
written+=RMAP_MAX_XFER_SIZE;
count-=RMAP_MAX_XFER_SIZE;
progress->setValue(written);
qApp->processEvents();
}
if(count>0)
{
for(int i=0;i<((int)count);i++)
{
writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+4] = (char)(((unsigned int)Value[i+written])&0xFF);
}
transactionID=manager->getRMAPtransactionID();
SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
RMAP_build_tx_request_header(
this->manager->destinationLogicalAddress,
this->manager->destinationKey,
this->manager->sourceLogicalAddress,
transactionID,
address+(written*4),
count*4,
writeBuffer+1);
manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(count*4) +1);
manager->getRMAPanswer(transactionID,&RMAPAckBuff);
free(RMAPAckBuff);
written+=count;
if(progress!=NULL)
{
progress->setValue(written);
qApp->processEvents();
}
}
return written;
}
unsigned int stardundeeSPW_USB::Read(unsigned int *Value, unsigned int count, unsigned int address)
{
char requestBuffer[RMAP_READ_HEADER_MIN_SZ+1];
char* RMAP_AnswerBuffer;
requestBuffer[0]=this->manager->linkNumber;//Link number
int transactionID = 0;
int read=0;
QProgressBar* progress=NULL;
SocExplorerAutoProgressBar autopb;
if(count>RMAP_MAX_XFER_SIZE)
{
progress= SocExplorerEngine::getProgressBar("Reading on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
autopb.setProgressBar(progress);
}
SocExplorerEngine::message(this->plugin,QString("Enter read function, count=%1, RMAP_MAX_XFER_SIZE=%2").arg(count).arg(RMAP_MAX_XFER_SIZE),2);
//Quite stupide loop, I guess that I always get the number of byte I asked for!
while((int)count>=(int)RMAP_MAX_XFER_SIZE)
{
transactionID = manager->getRMAPtransactionID();
SocExplorerEngine::message(this->plugin,QString("New transactionID:%1").arg(transactionID),2);
RMAP_build_rx_request_header(
this->manager->destinationLogicalAddress,
this->manager->destinationKey,
this->manager->sourceLogicalAddress,
transactionID,
address+(read*4),
RMAP_MAX_XFER_SIZE*4,
requestBuffer+1);
manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ+1);
int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
if(len==-1)
{
this->toggleBridgeConnection();
return 0;
}
for(int i=0;i<((len-13)/4);i++)
{
Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
}
free(RMAP_AnswerBuffer);
read+=RMAP_MAX_XFER_SIZE;
count-=RMAP_MAX_XFER_SIZE;
progress->setValue(read);
qApp->processEvents();
}
if((int)count>0)
{
transactionID = manager->getRMAPtransactionID();
SocExplorerEngine::message(this->plugin,QString("New transactionID: %1").arg(transactionID),2);
SocExplorerEngine::message(this->plugin,QString("Building request with:"),2);
SocExplorerEngine::message(this->plugin,QString("Address = %1").arg(address+(read*4),8,16),2);
SocExplorerEngine::message(this->plugin,QString("Size = %1").arg(count*4),2);
SocExplorerEngine::message(this->plugin,QString("Size + 13 = %1").arg((count*4)+13),2);
RMAP_build_rx_request_header(
this->manager->destinationLogicalAddress,
this->manager->destinationKey,
this->manager->sourceLogicalAddress,
transactionID,
address+(read*4),
count*4,
requestBuffer+1);
manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ+1);
int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
if(len==-1)
{
this->toggleBridgeConnection();
return 0;
}
for(int i=0;i<((len-13)/4);i++)
{
Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
}
free(RMAP_AnswerBuffer);
read+=count;
if(progress!=NULL)
{
progress->setValue(read);
qApp->processEvents();
}
}
return read;
}
void stardundeeSPW_USB::brickSelectionChanged(int brickIndex)
{
this->manager->selectedBrick = brickIndex-1;
SocExplorerEngine::message(plugin,QString("Changing brick index: %1").arg(manager->selectedBrick),1);
}
void stardundeeSPW_USB::linkNumberSelectionChanged(int linkIndex)
{
this->manager->linkNumber = linkIndex + 1;
SocExplorerEngine::message(plugin,QString("Changing Link Number: %1").arg(manager->linkNumber),1);
}
void stardundeeSPW_USB::linkSpeedSelectionChanged(const QString &linkSpeed)
{
this->manager->linkSpeed = linkSpeed.toInt();
SocExplorerEngine::message(plugin,QString("Changing Link Speed: %1").arg(manager->linkSpeed),1);
}
void stardundeeSPW_USB::sourceLogicalAddressChanged(const QString &sourceAddress)
{
this->manager->sourceLogicalAddress = sourceAddress.toInt();
SocExplorerEngine::message(plugin,QString("Changing Destination Key: %1").arg(manager->sourceLogicalAddress),1);
}
void stardundeeSPW_USB::destinationAddressChanged(const QString &rmapaddress)
{
this->manager->destinationLogicalAddress = rmapaddress.toInt();
SocExplorerEngine::message(plugin,QString("Changing RMAP address: %1").arg(manager->destinationLogicalAddress),1);
}
void stardundeeSPW_USB::destinationKeyChanged(const QString &key)
{
this->manager->destinationKey = key.toInt();
SocExplorerEngine::message(plugin,QString("Changing RMAP Key: %1").arg(manager->destinationKey),1);
}
void stardundeeSPW_USB::brickModeChanged( bool interfaceMode )
{
this->manager->interfaceMode = interfaceMode;
}
void stardundeeSPW_USB::timecodeFrequencyChanged(const QString &frequency)
{
this->manager->timecodeFrequency = frequency.toDouble();
this->manager->setTimecodeFrequency( this->manager->timecodeFrequency);
SocExplorerEngine::message(plugin,QString("Changing timecode frequency: %1").arg(manager->timecodeFrequency),1);
}
void stardundeeSPW_USB::startSendingTimecodes(bool onOff )
{
this->manager->sendTimecodePeriodically( onOff );
}
void stardundeeSPW_USB::rmapTimeoutChanged(const QString &timeout)
{
int tim=timeout.toInt();
if(tim<50)
{
tim = 50;
((StarDundeeGUI*)this->p_GUI)->setRmapTimeout(QString("%1").arg(tim));
}
this->manager->RMAPtimeout = tim;
SocExplorerEngine::message(plugin,QString("Changing RMAP Timeout: %1").arg(manager->RMAPtimeout),1);
}
void stardundeeSPW_USB::makeGUI(socexplorerplugin *parent)
{
this->p_GUI = new StarDundeeGUI();
// this->mainLayout = new QGridLayout(this->p_GUI);
connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(connectClicked()),this,SLOT(toggleBridgeConnection()));
connect(this->manager,SIGNAL(updateAvailableBrickCount(int)),((StarDundeeGUI*)this->p_GUI),SLOT(updateAvailableBrickCount(int)));
connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(brickSelectionChanged(int)),this,SLOT(brickSelectionChanged(int)));
connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(linkNumberSelectionChanged(int)),this,SLOT(linkNumberSelectionChanged(int)));
connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(linkSpeedSelectionChanged(QString)),this,SLOT(linkSpeedSelectionChanged(QString)));
connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(sourceLogicalAddressChanged(QString)),this,SLOT(sourceLogicalAddressChanged(QString)));
connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(rmapAddressChanged(QString)),this,SLOT(destinationAddressChanged(QString)));
connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(destinationKeyChanged(QString)),this,SLOT(destinationKeyChanged(QString)));
connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(rmapTimeoutChanged(QString)),this,SLOT(rmapTimeoutChanged(QString)));
connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(brickModeChanged(bool)), this, SLOT(brickModeChanged(bool)));
connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(timecodeFrequencyChange(QString)), this, SLOT(timecodeFrequencyChanged(QString)));
connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(startSendingTimecode(bool)), this, SLOT(startSendingTimecodes(bool)));
this->brickSelectionChanged( ((StarDundeeGUI*)this->p_GUI)->getBrickSelection());
this->linkNumberSelectionChanged( ((StarDundeeGUI*)this->p_GUI)->getLinkNumberSelection());
this->linkSpeedSelectionChanged( ((StarDundeeGUI*)this->p_GUI)->getLinkSpeedSelection());
this->sourceLogicalAddressChanged(((StarDundeeGUI*)this->p_GUI)->getSourceAddress());
this->destinationAddressChanged( ((StarDundeeGUI*)this->p_GUI)->getDestinationAddress());
this->destinationKeyChanged( ((StarDundeeGUI*)this->p_GUI)->getDestinationKey());
this->rmapTimeoutChanged( ((StarDundeeGUI*)this->p_GUI)->getRmapTimeout());
this->brickModeChanged( ((StarDundeeGUI*)this->p_GUI)->isBrickSetAsAnInterface());
connect(this,SIGNAL(SelectBrick(int)), ((StarDundeeGUI*)this->p_GUI),SLOT(selectBrick(int)));
connect(this,SIGNAL(SelectLinkNumber(int)), ((StarDundeeGUI*)this->p_GUI),SLOT(selectLinkNumber(int)));
connect(this,SIGNAL(SelectLinkSpeed(int)), ((StarDundeeGUI*)this->p_GUI),SLOT(selectLinkSpeed(int)));
connect(this,SIGNAL(SetDestinationKey(QString)), ((StarDundeeGUI*)this->p_GUI),SLOT(setDestinationKey(QString)));
connect(this,SIGNAL(SetDestinationAddress(QString)),((StarDundeeGUI*)this->p_GUI),SLOT(setDestinationAddress(QString)));
connect(this,SIGNAL(SetSourceAddress(QString)), ((StarDundeeGUI*)this->p_GUI),SLOT(setSourceAddress(QString)));
connect(this,SIGNAL(SetRmapTimeout(QString)), ((StarDundeeGUI*)this->p_GUI),SLOT(setRmapTimeout(QString)));
connect(this,SIGNAL(GetAvailableBrickCount()), ((StarDundeeGUI*)this->p_GUI),SLOT(getAvailableBrickCount()));
connect(this,SIGNAL(GetNbPacketsTransmittedToSpw()),((StarDundeeGUI*)this->p_GUI),SLOT(getNbPacketsTransmittedToSpw()));
connect(this,SIGNAL(GetNbCCSDSPacketsTransmittedToSpw()),
((StarDundeeGUI*)this->p_GUI),SLOT(getNbCCSDSPacketsTransmittedToSpw()));
connect(this,SIGNAL(SetBrickAsAnInterface(bool)), ((StarDundeeGUI*)this->p_GUI),SLOT(setBrickAsAnInterface(bool)));
connect(this,SIGNAL(SetBrickAsARouter(bool)), ((StarDundeeGUI*)this->p_GUI),SLOT(setBrickAsARouter(bool)));
connect(this,SIGNAL(BytesReceivedFromSpw(uint)), ((StarDundeeGUI*)this->p_GUI),SLOT(updateNbReceivedBytesFromSpw(uint)));
connect(this,SIGNAL(BytesTransmittedToSpw(uint)), ((StarDundeeGUI*)this->p_GUI),SLOT(updateNbTransmittedBytesToSpw(uint)));
connect(this, SIGNAL(CCSDSPacketTransmittedToSpw()),((StarDundeeGUI*)this->p_GUI),SLOT(updateCCSDSPacketTransmittedToSpw()));
connect(this,SIGNAL(SetTimecodeFrequency(double)), ((StarDundeeGUI*)this->p_GUI),SLOT(setTimecodeFrequency(QString)));
connect(this,SIGNAL(StartSendingTimecodes(bool)), ((StarDundeeGUI*)this->p_GUI),SLOT(setStartSendingTimecodes(bool)));
connect(this,SIGNAL(GetLinkNumber()), this->manager, SLOT(getLinkNumber()));
}
void stardundeeSPW_USB::sendPacketComingFromTCPServer(char *packet, int size)
{
char* data;
int i;
data = (char *) malloc( size + 5 );
data[0] = this->manager->linkNumber;
data[1] = this->manager->destinationLogicalAddress; // target logical address
data[2] = SPW_PROTO_ID_CCSDS; // protocol identifier
data[3] = 0x00; // reserved
data[4] = 0x00; // user application
for ( i=0; i<size; i++ )
{
data[i+5] = packet[i];
}
this->manager->sendPacket( data, size + 5);
free(data);
free(packet);
}
stardundeeSPW_USB_Manager::stardundeeSPW_USB_Manager(socexplorerplugin *plugin, QObject *parent)
:QThread((QObject*)parent)
{
this->RMAPtimeout = 2000;
this->handleMutex = new QMutex(QMutex::NonRecursive);
this->RMAP_AnswersSem = new QSemaphore(0);
this->RMAP_AnswersMtx=new QMutex(QMutex::Recursive);
this->RMAP_pending_transaction_IDsMtx=new QMutex(QMutex::Recursive);
this->plugin = plugin;
connected = false;
this->moveToThread(this);
}
stardundeeSPW_USB_Manager::~stardundeeSPW_USB_Manager()
{
this->terminate();
while (!this->isFinished()) {
this->usleep(1000);
}
}
void stardundeeSPW_USB_Manager::run()
{
USB_SPACEWIRE_PACKET_PROPERTIES properties;
USB_SPACEWIRE_ID pIdentifier=NULL;
USB_SPACEWIRE_STATUS stat;
SocExplorerEngine::message(this->plugin,"Starting Startdundee USB pooling thread",1);
char buffer[(RMAP_MAX_XFER_SIZE*4)+50];
while (!this->isInterruptionRequested())
{
if(this->connected)
{
handleMutex->lock();
SocExplorerEngine::message(this->plugin,"Looking for new RMAP packets",4);
if(USBSpaceWire_WaitOnReadPacketAvailable(hDevice,0.01))
{
SocExplorerEngine::message(this->plugin,"Got packet",2);
stat = USBSpaceWire_ReadPackets(hDevice, buffer, (RMAP_MAX_XFER_SIZE*4)+50,1, 1, &properties, &pIdentifier);
if (stat == TRANSFER_SUCCESS)
{
if(USBSpaceWire_GetReadTrafficType(&properties, 0) ==SPACEWIRE_TRAFFIC_PACKET)
{
SocExplorerEngine::message(this->plugin,"It's a SPW packet",2);
if(USBSpaceWire_GetReadEOPStatus(&properties, 0)== SPACEWIRE_USB_EOP)
{
SocExplorerEngine::message(this->plugin,"Got end of packet",2);
emit bytesReceivedFromSpw( properties.len );
if(buffer[1]==(char)SPW_PROTO_ID_RMAP) //RMAP packet
{
RMAP_Answer* packet;
SocExplorerEngine::message(this->plugin,"Got RMAP packet",2);
SocExplorerEngine::message(this->plugin,QString("Rmap packet size %1").arg(properties.len),2);
char* packetbuffer = (char*)malloc(properties.len);
memcpy(packetbuffer,buffer,properties.len);
USBSpaceWire_FreeRead(hDevice, pIdentifier);
pIdentifier = NULL;
handleMutex->unlock();
if(properties.len==8)
{
packet=new RMAP_Answer(RMAP_get_transactionID(buffer),packetbuffer,properties.len);
}
else
{
packet=new RMAP_Answer(RMAP_get_transactionID(buffer+1),packetbuffer,properties.len);
}
RMAP_AnswersMtx->lock();
RMAP_Answers.append(packet);
RMAP_AnswersMtx->unlock();
RMAP_AnswersSem->release();
}
else //any non-rmap packet will be pushed to the network
{
char* packetbuffer = (char*)malloc(properties.len);
memcpy(packetbuffer,buffer,properties.len);
emit emitPacket(packetbuffer,properties.len);
USBSpaceWire_FreeRead(hDevice, pIdentifier);
handleMutex->unlock();
SocExplorerEngine::message(this->plugin,"Got SPW packet",2);
}
}
else
{
SocExplorerEngine::message(this->plugin,"No EOP received",2);
}
}
}
else
{
USBSpaceWire_FreeRead(hDevice, pIdentifier);
handleMutex->unlock();
}
}
else
{
USBSpaceWire_FreeRead(hDevice, pIdentifier);
handleMutex->unlock();
}
}
else
{
//do some sanity checks!
int list = USBSpaceWire_ListDevices();
if(this->brickList!=list)
{
this->brickList = list;
emit updateAvailableBrickCount(this->brickList);
}
usleep(RMAPtimeout/2);
}
usleep(1000);
}
SocExplorerEngine::message(this->plugin,"Exiting Startdundee USB pooling thread",1);
}
bool stardundeeSPW_USB_Manager::connectBridge()
{
bool ret;
if (this->interfaceMode == BRICK_IS_SET_AS_AN_INTERFACE)
{
ret = connectBridgeAsInterface();
}
else if (this->interfaceMode == BRICK_IS_SET_AS_A_ROUTER)
{
ret = connectBridgeAsRouter();
}
else
{
ret = false;
}
return ret;
}
bool stardundeeSPW_USB_Manager::connectBridgeAsInterface()
{
QMutexLocker mlock(this->handleMutex);
int status;
U32 statusControl;
this->connected = false;
if (!USBSpaceWire_Open(&hDevice, this->selectedBrick)) // Open the USB device
{
SocExplorerEngine::message(this->plugin,"stardundee *** Open *** ERROR: USBSpaceWire_Open(&hDevice, 0))",0);
return false;
}
SocExplorerEngine::message(this->plugin,"stardundee *** Open *** USBSpaceWire_Open successful",0);
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);
// 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)
{
SocExplorerEngine::message(this->plugin,"ERROR CFGSpaceWire_SetBrickBaseTransmitRate",1);
return false;
}
else
{
SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_SetBrickBaseTransmitRate, base rate = 100 MHz",1);
}
// read the link status
if (CFGSpaceWire_GetLinkStatusControl(hDevice, this->linkNumber, &statusControl) != CFG_TRANSFER_SUCCESS)
{
SocExplorerEngine::message(this->plugin,"Could not read link status control for link " + QString::number(this->linkNumber),1);
return false;
}
else
{
SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_GetLinkStatusControl of link " + QString::number(this->linkNumber),1);
// 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, this->linkNumber, statusControl) != CFG_TRANSFER_SUCCESS)
{
SocExplorerEngine::message(this->plugin,"Could not set the link status control for link " + QString::number(this->linkNumber),1);
return false;
}
else
{
SocExplorerEngine::message(this->plugin,"Set the link status control for link " + QString::number(this->linkNumber),1);
}
}
if (CFGSpaceWire_SetAsInterface(hDevice, 1, 0) != CFG_TRANSFER_SUCCESS)
{
SocExplorerEngine::message(this->plugin,"Could not set the device to be an interface",1);
return false;
}
else
{
SocExplorerEngine::message(this->plugin,"Device set to be an interface",1);
}
USBSpaceWire_RegisterReceiveOnAllPorts(hDevice); // Register to receive on all ports
USBSpaceWire_ClearEndpoints(hDevice); // clear the USB endpoints
USBSpaceWire_SetTimeout(hDevice,1.0);
SocExplorerEngine::message(this->plugin,"The driver's current send buffer size is " + QString::number(USBSpaceWire_GetDriverSendBufferSize(hDevice)) + " bytes",1);
SocExplorerEngine::message(this->plugin,"The driver's current read buffer size is " + QString::number(USBSpaceWire_GetDriverReadBufferSize(hDevice)) + " bytes",1);
SocExplorerEngine::message(this->plugin,"USBSpaceWire_IsReadThrottling is " + QString::number(USBSpaceWire_IsReadThrottling(hDevice)),1);
this->connected = true;
return true;
}
bool stardundeeSPW_USB_Manager::connectBridgeAsRouter()
{
QMutexLocker mlock(this->handleMutex);
int status;
U32 statusControl;
unsigned int linkStatus1;
unsigned int linkStatus2;
unsigned char linkNumber;
unsigned char deviceIsAnInterface;
if (!USBSpaceWire_Open(&hDevice, this->selectedBrick)) // Open the USB device
{
SocExplorerEngine::message(this->plugin,"stardundee *** Open *** ERROR: USBSpaceWire_Open(&hDevice, 0))");
return false;
}
SocExplorerEngine::message(this->plugin,"stardundee *** Open *** USBSpaceWire_Open successful, device number: "
+ QString::number(this->selectedBrick));
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
// This affects just the operations performed by the Configuration Library and does not affect the packets
// sent and received using the driver API.
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)
{
SocExplorerEngine::message(this->plugin,"ERROR CFGSpaceWire_SetBrickBaseTransmitRate");
}
else SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_SetBrickBaseTransmitRate, base rate = 100 MHz");
//*********************
// LINK 1 CONFIGURATION
linkNumber = 1;
if (CFGSpaceWire_GetLinkStatusControl(hDevice, linkNumber, &statusControl) != CFG_TRANSFER_SUCCESS)
SocExplorerEngine::message(this->plugin,"Could not read link status control for link " + QString::number(linkNumber));
else
{
SocExplorerEngine::message(this->plugin,"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)
SocExplorerEngine::message(this->plugin,"Could not set the link status control for link " + QString::number(linkNumber));
else
SocExplorerEngine::message(this->plugin,"link status control for link " + QString::number(0x01) + " is set");
}
//*********************
// LINK 2 CONFIGURATION
linkNumber = 2;
if (CFGSpaceWire_GetLinkStatusControl(hDevice, linkNumber, &statusControl) != CFG_TRANSFER_SUCCESS)
SocExplorerEngine::message(this->plugin,"Could not read link status control for link " + QString::number(linkNumber));
else
{
SocExplorerEngine::message(this->plugin,"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)
SocExplorerEngine::message(this->plugin,"Could not set the link status control for link " + QString::number(linkNumber));
else
SocExplorerEngine::message(this->plugin,"link status control for link " + QString::number(linkNumber) + " is set");
}
//***************************
// SET THE DEVICE AS A ROUTER
deviceIsAnInterface = 0; // 0 = router, 1 = interface
if (CFGSpaceWire_SetAsInterface(hDevice, deviceIsAnInterface, 0) != CFG_TRANSFER_SUCCESS)
SocExplorerEngine::message(this->plugin,"Could not set the device to be an interface");
else
SocExplorerEngine::message(this->plugin,"Device is an interface: " + QString::number(deviceIsAnInterface) + " (1 => true, 0 => false)");
setRoutingTableEntry(0xfe, 0x02, 0); // [0010] => route 0xfe on port 1
setRoutingTableEntry(32 , 0x08, 0); // [1000] => route 32 on port 3
USBSpaceWire_RegisterReceiveOnAllPorts(hDevice); // Register to receive on port 1 only
USBSpaceWire_ClearEndpoints(hDevice); // clear the USB endpoints
SocExplorerEngine::message(this->plugin,"The driver's current send buffer size is " + QString::number(USBSpaceWire_GetDriverSendBufferSize(hDevice)) + " bytes");
SocExplorerEngine::message(this->plugin,"The driver's current read buffer size is " + QString::number(USBSpaceWire_GetDriverReadBufferSize(hDevice)) + " bytes");
SocExplorerEngine::message(this->plugin,"USBSpaceWire_IsReadThrottling is " + QString::number(USBSpaceWire_IsReadThrottling(hDevice)));
//************
// test Link 1 and Link 2
linkStatus1 = getLinkStatus(0x01);
linkStatus2 = getLinkStatus(0x02);
if ((linkStatus1==1) || (linkStatus2==1))
{
initializeTimecodeGeneration();
this->connected=true;
return true;
}
else
{
statusLink1->setText("Link 1 status code: " + QString::number(linkStatus1));
statusLink2->setText("Link 2 status code: " + QString::number(linkStatus2));
starDundeeStatusQueryDialog->exec();
this->connected = false;
return false;
}
}
void stardundeeSPW_USB_Manager::initDialog( void )
{
// STAR DUNDEE STATUS QUERY DIALOG
starDundeeStatusQueryDialog = new QDialog;
starDundeeStatusQueryDialogLayout = new QGridLayout;
starDundeeStatusQueryDialogLabel = new QLabel(tr("SpaceWire links state"));
starDundeeStatusQueryContinueButton = new QPushButton(tr("Continue"));
starDundeeStatusQueryRetryButton = new QPushButton(tr("Retry"));
starDundeeStatusQueryAbortButton = new QPushButton(tr("Abort"));
statusLink1 = new QLabel(tr("Link 1 status code: -"));
statusLink2 = new QLabel(tr("Link 2 status code: -"));
starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryDialogLabel, 0, 0, 1, 2);
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);
starDundeeStatusQueryDialog->setLayout(starDundeeStatusQueryDialogLayout);
}
unsigned char stardundeeSPW_USB_Manager::setRoutingTableEntry(int tableEntry, U32 dwOutputPorts, char bDelHead)
{
U32 routingTableEntry;
// SET THE ROUTING TABLE ENTRY FOR LOGICAL ADDRESSING, TARGET entryNumber
if (CFGSpaceWire_ClearRoutingTableEntry(hDevice, tableEntry) != CFG_TRANSFER_SUCCESS)
{
SocExplorerEngine::message(this->plugin,"Could not clear routing table entry " + QString::number(tableEntry));
}
// Build the routing table entry
CFGSpaceWire_RTBuildRoutingTableEntry(&routingTableEntry,
dwOutputPorts, // route out of port dwOutputPorts
bDelHead, // header deletion is enabled [1] or disabled [0]
0); // priority normal
// Set the routing table entry for logical address tableEntry
if (CFGSpaceWire_SetRoutingTableEntry(hDevice, tableEntry, routingTableEntry) != CFG_TRANSFER_SUCCESS)
{
SocExplorerEngine::message(this->plugin,"Could not set routing table entry [" + QString::number(tableEntry) + "]");
}
else SocExplorerEngine::message(this->plugin,"Routing table entry [" + QString::number(tableEntry) + "] set" );
return 1;
}
unsigned int stardundeeSPW_USB_Manager::getRoutingTableEntry(int tableEntry)
{
U32 routingTableEntry, outputPorts;
char enabled, delHead, priority;
int portNum;
SocExplorerEngine::message(this->plugin,"GetRoutingTableEntry [" + QString::number(tableEntry) + "]");
// Read the routing table entry
if (CFGSpaceWire_GetRoutingTableEntry(hDevice, tableEntry, &routingTableEntry) != CFG_TRANSFER_SUCCESS)
{
SocExplorerEngine::message(this->plugin,"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);
SocExplorerEngine::message(this->plugin,"CFGSpaceWire_RTIsEnabled : " + QString::number(enabled));
SocExplorerEngine::message(this->plugin,"CFGSpaceWire_RTIsDelHead : " + QString::number(delHead));
SocExplorerEngine::message(this->plugin,"CFGSpaceWire_RTIsPriority : " + QString::number(priority));
SocExplorerEngine::message(this->plugin,"CFGSpaceWire_RTGetOutputPorts : ");
for (portNum = 0; portNum < 32; portNum++)
{
if (outputPorts & (1 << portNum))
{
SocExplorerEngine::message(this->plugin,QString::number(portNum));
}
}
}
return 1;
}
void stardundeeSPW_USB_Manager::initializeTimecodeGeneration()
{
U32 dwTickEnableStatus;
U32 rtr_clk_freq;
// (1) RESET
if (!USBSpaceWire_TC_Reset(hDevice))
SocExplorerEngine::message(this->plugin,"ERR *** in Open *** Could not reset timecodes\n");
// (2) Clear the tick enable register
if (CFGSpaceWire_SetTickEnableStatus(hDevice, 6) != CFG_TRANSFER_SUCCESS)
SocExplorerEngine::message(this->plugin,"Could not clear the tick enable register");
else
SocExplorerEngine::message(this->plugin,"Cleared the tick enable register");
// (3) get the tick status
CFGSpaceWire_GetTickEnableStatus(hDevice, &dwTickEnableStatus);
SocExplorerEngine::message(this->plugin,"OK *** in Open *** CFGSpaceWire_GetTickEnableStatus, code is " + QString::number(dwTickEnableStatus, 2));
// (4) enable external timecode selection
if(!USBSpaceWire_TC_EnableExternalTimecodeSelection(hDevice,0))
SocExplorerEngine::message(this->plugin,"ERR *** disable external timecode selection");
rtr_clk_freq = USBSpaceWire_TC_GetClockFrequency(hDevice);
SocExplorerEngine::message(this->plugin,"clock frequency = " + QString::number(rtr_clk_freq) );
//**************************************************
// auto _ tick _ freq = rtr _ clk _ freq / freqCount
if (!USBSpaceWire_TC_SetAutoTickInFrequency(hDevice, rtr_clk_freq) )
SocExplorerEngine::message(this->plugin,"Could not set the tick-in frequency");
}
unsigned int stardundeeSPW_USB_Manager::getLinkStatus(unsigned char link)
{
U32 statusControl, errorStatus, portType;
U32 linkStatus, operatingSpeed, outputPortConnection;
char isLinkRunning, isAutoStart, isStart, isDisabled, isTristate;
// Read the link status control register
if (CFGSpaceWire_GetLinkStatusControl(hDevice, link, &statusControl) != CFG_TRANSFER_SUCCESS)
{
SocExplorerEngine::message(this->plugin,"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);
}
else if (portType == CFG_SPACEWIRE_EXTERNAL_PORT)
{
CFGSpaceWire_LSExternalErrorStatus(statusControl, &errorStatus);
}
else
{
CFGSpaceWire_LSErrorStatus(statusControl, &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);
}
SocExplorerEngine::message(this->plugin,"status of link " + QString::number(link)
+" is " + dwLinkStatusQString[linkStatus]);
if (linkStatus == 5)
{
return 1;
}
else return 0;
}
bool stardundeeSPW_USB_Manager::disconnectBridge()
{
this->handleMutex->lock();
USBSpaceWire_Close(hDevice); // Close the device
SocExplorerEngine::message(this->plugin,"stardundee *** Close *** USBSpaceWire_Close, device: " + QString::number(0),0);
USBSpaceWire_UnregisterReceiveOnAllPorts(hDevice); // Stop receiving on all ports
this->handleMutex->unlock();
this->RMAP_pending_transaction_IDsMtx->lock();
this->RMAP_pending_transaction_IDs.clear();
this->RMAP_pending_transaction_IDsMtx->unlock();
this->RMAP_AnswersMtx->lock();
this->RMAP_Answers.clear();
this->RMAP_AnswersMtx->unlock();
this->RMAP_AnswersSem->acquire(this->RMAP_AnswersSem->available());
return true;
}
int stardundeeSPW_USB_Manager::getRMAPtransactionID()
{
this->RMAP_pending_transaction_IDsMtx->lock();
int ID=0;
bool found=true;
while(ID<511)
{
for(int i=0;i<RMAP_pending_transaction_IDs.count();i++)
{
if(RMAP_pending_transaction_IDs[i]==ID)found=false;
}
if(found==true)break;
ID++;
found = true;
}
if(found)
{
RMAP_pending_transaction_IDs.append(ID);
}
this->RMAP_pending_transaction_IDsMtx->unlock();
return ID;
}
int stardundeeSPW_USB_Manager::getRMAPanswer(int transactionID, char **buffer)
{
QTime timeout;
*buffer=NULL;
int count=0;
SocExplorerEngine::message(this->plugin,"Looking for RMAP answer",2);
timeout.start();
while (*buffer==NULL)
{
this->RMAP_AnswersMtx->lock();
SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_Answers stack",2);
SocExplorerEngine::message(this->plugin,QString("%1 packet(s) available in RMAP_Answers stack").arg(RMAP_Answers.count()),2);
for(int i=0;i<RMAP_Answers.count();i++)
{
SocExplorerEngine::message(this->plugin,QString("Packet %1 ID=%2").arg(i).arg(RMAP_Answers[i]->transactionID),2);
if(RMAP_Answers[i]->transactionID==transactionID)
{
this->RMAP_pending_transaction_IDsMtx->lock();
SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_pending_transaction_ID stack",2);
for(int j=0;j<RMAP_pending_transaction_IDs.count();j++)
{
if(RMAP_pending_transaction_IDs[j]==transactionID)
{
RMAP_pending_transaction_IDs.removeAt(j);
}
}
this->RMAP_pending_transaction_IDsMtx->unlock();
*buffer = RMAP_Answers[i]->data;
count = RMAP_Answers[i]->len;
RMAP_Answer* tmp=RMAP_Answers[i];
RMAP_Answers.removeAt(i);
delete tmp;
}
}
this->RMAP_AnswersMtx->unlock();
//if no answer found in the stack wait until a new packet is pushed
SocExplorerEngine::message(this->plugin,"waiting until a new packet is pushed",2);
if(*buffer==NULL)
{
while (0==this->RMAP_AnswersSem->available())
{
SocExplorerEngine::message(this->plugin,QString("this->RMAP_AnswersSem->available() = %1").arg(this->RMAP_AnswersSem->available()),2);
if(timeout.elapsed()>=RMAPtimeout)
{
SocExplorerEngine::message(this->plugin,"Timeout reached giving up!",2);
return -1;
}
usleep(1000);
}
this->RMAP_AnswersSem->acquire();
}
}
return count;
}
bool stardundeeSPW_USB_Manager::sendPacket(char *packet, int size)
{
char protocoleIdentifier;
USB_SPACEWIRE_STATUS result;
USB_SPACEWIRE_ID pIdentifier;
SocExplorerEngine::message(this->plugin,"Sending SPW packet",2);
this->handleMutex->lock();
result = USBSpaceWire_SendPacket(hDevice,packet,size,1, &pIdentifier);
if (result != TRANSFER_SUCCESS)
{
SocExplorerEngine::message(this->plugin,"ERR sending the READ command ",2);
this->handleMutex->unlock();
return false;
}
else
{
emit bytesTransmittedToSpw( size-1 ); // -1 is for removing the first bytes added to the packet to route to the right link
// read the protocole identifier
protocoleIdentifier = packet[2];
if (protocoleIdentifier == SPW_PROTO_ID_CCSDS)
emit ccsdsPacketTransmittedToSpw();
SocExplorerEngine::message(this->plugin,"Packet sent",2);
USBSpaceWire_FreeSend(hDevice, pIdentifier);
}
this->handleMutex->unlock();
return true;
}
void stardundeeSPW_USB_Manager::pushRmapPacket(char *packet, int len)
{
char* packetbuffer = (char*)malloc(len);
memcpy(packetbuffer,packet,len);
RMAP_Answer* RMPAPpacket=new RMAP_Answer(RMAP_get_transactionID(packetbuffer+1),packetbuffer,len);
RMAP_AnswersMtx->lock();
RMAP_Answers.append(RMPAPpacket);
RMAP_AnswersMtx->unlock();
}
void stardundeeSPW_USB_Manager::sendTimecodePeriodically( bool onOff )
{
if (onOff == true)
{
if (!USBSpaceWire_TC_EnableAutoTickIn(hDevice, 1, 1))
SocExplorerEngine::message(this->plugin,"Could not enable auto tick-in");
}
else
{
if (!USBSpaceWire_TC_EnableAutoTickIn(hDevice, 0, 0))
SocExplorerEngine::message(this->plugin,"Could not disable auto tick-in");
}
}
int stardundeeSPW_USB_Manager::getLinkNumber( void )
{
return this->linkNumber;
}
void stardundeeSPW_USB_Manager::setTimecodeFrequency(double requestedFrequency)
{
U32 rtr_clk_freq;
U32 freqCount;
double freqCountInDouble;
double currentFrequency;
rtr_clk_freq = USBSpaceWire_TC_GetClockFrequency(hDevice);
freqCountInDouble = ((double) rtr_clk_freq) / requestedFrequency;
freqCount = (unsigned int) freqCountInDouble;
currentFrequency = ((double) rtr_clk_freq) / ((double) freqCount);
//**************************************************
// auto _ tick _ freq = rtr _ clk _ freq / freqCount
if (!USBSpaceWire_TC_SetAutoTickInFrequency(hDevice, freqCount) )
SocExplorerEngine::message(this->plugin,"Could not set the tick-in frequency");
else
SocExplorerEngine::message(this->plugin,"tick frequency set to " + QString::number(currentFrequency) +" Hz");
}