##// END OF EJS Templates
Added missing threading protections
Jeandet Alexis -
r69:039eabb0d39f default
parent child
Show More
@@ -1,1103 +1,1108
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the SocExplorer Software
3 3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 3 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@member.fsf.org
21 21 ----------------------------------------------------------------------------*/
22 22
23 23 #include "stardundeespw_usb.h"
24 24 #include "fakestardundeespwusb_lib.h"
25 25 #include <socexplorerengine.h>
26 26 #include <qhexedit.h>
27 27
28 28 QString dwLinkStatusQString[6] = {
29 29 "CFG_SPACEWIRE_ERROR_RESET",
30 30 "CFG_SPACEWIRE_ERROR_WAIT",
31 31 "CFG_SPACEWIRE_READY",
32 32 "CFG_SPACEWIRE_STARTED",
33 33 "CFG_SPACEWIRE_CONNECTING",
34 34 "CFG_SPACEWIRE_RUN"
35 35 };
36 36
37 37 stardundeeSPW_USB::stardundeeSPW_USB(socexplorerplugin *parent) :
38 38 abstractSpwBridge(parent)
39 39 {
40 40 Q_UNUSED(parent)
41 41 this->manager = new stardundeeSPW_USB_Manager(parent,this);
42 42 makeGUI(parent);
43 43 this->manager->start();
44 44 connect(this->manager,SIGNAL(emitPacket(char*,int)),this,SIGNAL(pushPacketOverTCP(char*,int)));
45 45 connect(this->manager, SIGNAL(bytesReceivedFromSpw(uint)), this, SIGNAL(BytesReceivedFromSpw(uint)));
46 46 connect(this->manager, SIGNAL(bytesTransmittedToSpw(uint)), this, SIGNAL(BytesTransmittedToSpw(uint)));
47 47 connect(this->manager, SIGNAL(ccsdsPacketTransmittedToSpw()), this, SIGNAL(CCSDSPacketTransmittedToSpw()));
48 48 }
49 49
50 50 stardundeeSPW_USB::~stardundeeSPW_USB()
51 51 {
52 52 this->manager->requestInterruption();
53 53 while(this->manager->isRunning());
54 54 }
55 55
56 56 void stardundeeSPW_USB::toggleBridgeConnection()
57 57 {
58 58 if(this->plugin->isConnected())
59 59 {
60 60 this->disconnectBridge();
61 61 }
62 62 else
63 63 {
64 64 this->connectBridge();
65 65 }
66 66 }
67 67
68 68 bool stardundeeSPW_USB::connectBridge()
69 69 {
70 70 if(this->manager->connectBridge())
71 71 {
72 72 this->timecodeFrequencyChanged( ((StarDundeeGUI*)this->p_GUI)->getTimecodeFrequency());
73 73 this->startSendingTimecodes( ((StarDundeeGUI*)this->p_GUI)->getStartSendingTimecodes());
74 74 ((StarDundeeGUI*)this->p_GUI)->lock(true);
75 75 emit setConnected(true);
76 76 return true;
77 77 }
78 78 return false;
79 79 }
80 80
81 81 bool stardundeeSPW_USB::disconnectBridge()
82 82 {
83 83 if(this->manager->disconnectBridge())
84 84 {
85 85 ((StarDundeeGUI*)this->p_GUI)->lock(false);
86 86 emit setConnected(false);
87 87 return true;
88 88 }
89 89 return false;
90 90 }
91 91
92 92 int stardundeeSPW_USB::pushRMAPPacket(char *packet, int size)
93 93 {
94 94 return this->manager->sendPacket(packet,size);
95 95 }
96 96
97 97 unsigned int stardundeeSPW_USB::Write(unsigned int *Value, unsigned int count, unsigned int address)
98 98 {
99 99 char writeBuffer[RMAP_WRITE_PACKET_MIN_SZ((RMAP_MAX_XFER_SIZE*4))+1];
100 100 char *RMAPAckBuff;
101 101 writeBuffer[0]=this->manager->linkNumber;//Link number
102 102 int transactionID = 0;
103 103 int written=0;
104 104 SocExplorerEngine::message(this->plugin,"Enter Write function",2);
105 105 QProgressBar* progress=NULL;
106 106 SocExplorerAutoProgressBar autopb;
107 107 if(count>RMAP_MAX_XFER_SIZE)
108 108 {
109 109 progress= SocExplorerEngine::getProgressBar("Writing on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
110 110 autopb.setProgressBar(progress);
111 111 }
112 112 //Quite stupide loop, I guess that I always get the number of byte I asked for!
113 113 while(count>=RMAP_MAX_XFER_SIZE)
114 114 {
115 115 for(int i=0;i<(RMAP_MAX_XFER_SIZE);i++)
116 116 {
117 117 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
118 118 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
119 119 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
120 120 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+4] = (char)(((unsigned int)Value[i+written])&0xFF);
121 121 }
122 122 transactionID=manager->getRMAPtransactionID();
123 123 SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
124 124 RMAP_build_tx_request_header(
125 125 this->manager->destinationLogicalAddress,
126 126 this->manager->destinationKey,
127 127 this->manager->sourceLogicalAddress,
128 128 transactionID,
129 129 address+(written*4),
130 130 RMAP_MAX_XFER_SIZE*4,
131 131 writeBuffer+1);
132 132 manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(RMAP_MAX_XFER_SIZE*4)+1);
133 133 manager->getRMAPanswer(transactionID,&RMAPAckBuff);
134 134 free(RMAPAckBuff);
135 135 written+=RMAP_MAX_XFER_SIZE;
136 136 count-=RMAP_MAX_XFER_SIZE;
137 137 progress->setValue(written);
138 138 qApp->processEvents();
139 139 }
140 140 if(count>0)
141 141 {
142 142 for(int i=0;i<((int)count);i++)
143 143 {
144 144 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
145 145 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
146 146 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
147 147 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+4] = (char)(((unsigned int)Value[i+written])&0xFF);
148 148 }
149 149 transactionID=manager->getRMAPtransactionID();
150 150 SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
151 151 RMAP_build_tx_request_header(
152 152 this->manager->destinationLogicalAddress,
153 153 this->manager->destinationKey,
154 154 this->manager->sourceLogicalAddress,
155 155 transactionID,
156 156 address+(written*4),
157 157 count*4,
158 158 writeBuffer+1);
159 159 manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(count*4) +1);
160 160 manager->getRMAPanswer(transactionID,&RMAPAckBuff);
161 161 free(RMAPAckBuff);
162 162 written+=count;
163 163 if(progress!=NULL)
164 164 {
165 165 progress->setValue(written);
166 166 qApp->processEvents();
167 167 }
168 168 }
169 169 return written;
170 170 }
171 171
172 172 unsigned int stardundeeSPW_USB::Read(unsigned int *Value, unsigned int count, unsigned int address)
173 173 {
174 174 char requestBuffer[RMAP_READ_HEADER_MIN_SZ+1];
175 175 char* RMAP_AnswerBuffer;
176 176 requestBuffer[0]=this->manager->linkNumber;//Link number
177 177 int transactionID = 0;
178 178 int read=0;
179 179 QProgressBar* progress=NULL;
180 180 SocExplorerAutoProgressBar autopb;
181 181 if(count>RMAP_MAX_XFER_SIZE)
182 182 {
183 183 progress= SocExplorerEngine::getProgressBar("Reading on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
184 184 autopb.setProgressBar(progress);
185 185 }
186 186 SocExplorerEngine::message(this->plugin,QString("Enter read function, count=%1, RMAP_MAX_XFER_SIZE=%2").arg(count).arg(RMAP_MAX_XFER_SIZE),2);
187 187
188 188 //Quite stupide loop, I guess that I always get the number of byte I asked for!
189 189 while((int)count>=(int)RMAP_MAX_XFER_SIZE)
190 190 {
191 191 transactionID = manager->getRMAPtransactionID();
192 192 SocExplorerEngine::message(this->plugin,QString("New transactionID:%1").arg(transactionID),2);
193 193 RMAP_build_rx_request_header(
194 194 this->manager->destinationLogicalAddress,
195 195 this->manager->destinationKey,
196 196 this->manager->sourceLogicalAddress,
197 197 transactionID,
198 198 address+(read*4),
199 199 RMAP_MAX_XFER_SIZE*4,
200 200 requestBuffer+1);
201 201 manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ+1);
202 202 int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
203 203 if(len==-1)
204 204 {
205 205 this->toggleBridgeConnection();
206 206 return 0;
207 207 }
208 208 for(int i=0;i<((len-13)/4);i++)
209 209 {
210 210 Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
211 211 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
212 212 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
213 213 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
214 214 }
215 215 free(RMAP_AnswerBuffer);
216 216 read+=RMAP_MAX_XFER_SIZE;
217 217 count-=RMAP_MAX_XFER_SIZE;
218 218 progress->setValue(read);
219 219 qApp->processEvents();
220 220 }
221 221 if((int)count>0)
222 222 {
223 223 transactionID = manager->getRMAPtransactionID();
224 224 SocExplorerEngine::message(this->plugin,QString("New transactionID: %1").arg(transactionID),2);
225 225 SocExplorerEngine::message(this->plugin,QString("Building request with:"),2);
226 226 SocExplorerEngine::message(this->plugin,QString("Address = %1").arg(address+(read*4),8,16),2);
227 227 SocExplorerEngine::message(this->plugin,QString("Size = %1").arg(count*4),2);
228 228 SocExplorerEngine::message(this->plugin,QString("Size + 13 = %1").arg((count*4)+13),2);
229 229 RMAP_build_rx_request_header(
230 230 this->manager->destinationLogicalAddress,
231 231 this->manager->destinationKey,
232 232 this->manager->sourceLogicalAddress,
233 233 transactionID,
234 234 address+(read*4),
235 235 count*4,
236 236 requestBuffer+1);
237 237 manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ+1);
238 238 int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
239 239 if(len==-1)
240 240 {
241 241 this->toggleBridgeConnection();
242 242 return 0;
243 243 }
244 244 for(int i=0;i<((len-13)/4);i++)
245 245 {
246 246 Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
247 247 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
248 248 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
249 249 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
250 250 }
251 251 free(RMAP_AnswerBuffer);
252 252 read+=count;
253 253 if(progress!=NULL)
254 254 {
255 255 progress->setValue(read);
256 256 qApp->processEvents();
257 257 }
258 258 }
259 259 return read;
260 260 }
261 261
262 262 void stardundeeSPW_USB::brickSelectionChanged(int brickIndex)
263 263 {
264 264 this->manager->selectedBrick = brickIndex-1;
265 265 SocExplorerEngine::message(plugin,QString("Changing brick index: %1").arg(manager->selectedBrick),1);
266 266 }
267 267
268 268 void stardundeeSPW_USB::linkNumberSelectionChanged(int linkIndex)
269 269 {
270 270 this->manager->linkNumber = linkIndex + 1;
271 271 SocExplorerEngine::message(plugin,QString("Changing Link Number: %1").arg(manager->linkNumber),1);
272 272 }
273 273
274 274 void stardundeeSPW_USB::linkSpeedSelectionChanged(const QString &linkSpeed)
275 275 {
276 276 this->manager->linkSpeed = linkSpeed.toInt();
277 277
278 278 SocExplorerEngine::message(plugin,QString("Changing Link Speed: %1").arg(manager->linkSpeed),1);
279 279 }
280 280
281 281 void stardundeeSPW_USB::sourceLogicalAddressChanged(const QString &sourceAddress)
282 282 {
283 283 this->manager->sourceLogicalAddress = sourceAddress.toInt();
284 284 SocExplorerEngine::message(plugin,QString("Changing Destination Key: %1").arg(manager->sourceLogicalAddress),1);
285 285 }
286 286
287 287 void stardundeeSPW_USB::destinationAddressChanged(const QString &rmapaddress)
288 288 {
289 289 this->manager->destinationLogicalAddress = rmapaddress.toInt();
290 290 SocExplorerEngine::message(plugin,QString("Changing RMAP address: %1").arg(manager->destinationLogicalAddress),1);
291 291 }
292 292
293 293 void stardundeeSPW_USB::destinationKeyChanged(const QString &key)
294 294 {
295 295 this->manager->destinationKey = key.toInt();
296 296 SocExplorerEngine::message(plugin,QString("Changing RMAP Key: %1").arg(manager->destinationKey),1);
297 297 }
298 298
299 299 void stardundeeSPW_USB::brickModeChanged( bool interfaceMode )
300 300 {
301 301 this->manager->interfaceMode = interfaceMode;
302 302 }
303 303
304 304 void stardundeeSPW_USB::timecodeFrequencyChanged(const QString &frequency)
305 305 {
306 306 this->manager->timecodeFrequency = frequency.toDouble();
307 307 this->manager->setTimecodeFrequency( this->manager->timecodeFrequency);
308 308 SocExplorerEngine::message(plugin,QString("Changing timecode frequency: %1").arg(manager->timecodeFrequency),1);
309 309 }
310 310
311 311 void stardundeeSPW_USB::startSendingTimecodes(bool onOff )
312 312 {
313 313 this->manager->sendTimecodePeriodically( onOff );
314 314 }
315 315
316 316 void stardundeeSPW_USB::rmapTimeoutChanged(const QString &timeout)
317 317 {
318 318 int tim=timeout.toInt();
319 319 if(tim<50)
320 320 {
321 321 tim = 50;
322 322 ((StarDundeeGUI*)this->p_GUI)->setRmapTimeout(QString("%1").arg(tim));
323 323 }
324 324 this->manager->RMAPtimeout = tim;
325 325 SocExplorerEngine::message(plugin,QString("Changing RMAP Timeout: %1").arg(manager->RMAPtimeout),1);
326 326 }
327 327
328 328 void stardundeeSPW_USB::makeGUI(socexplorerplugin *parent)
329 329 {
330 330 Q_UNUSED(parent)
331 331 this->p_GUI = new StarDundeeGUI();
332 332 // this->mainLayout = new QGridLayout(this->p_GUI);
333 333 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(connectClicked()),this,SLOT(toggleBridgeConnection()));
334 334 connect(this->manager,SIGNAL(updateAvailableBrickCount(int)),((StarDundeeGUI*)this->p_GUI),SLOT(updateAvailableBrickCount(int)));
335 335 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(brickSelectionChanged(int)),this,SLOT(brickSelectionChanged(int)));
336 336 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(linkNumberSelectionChanged(int)),this,SLOT(linkNumberSelectionChanged(int)));
337 337 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(linkSpeedSelectionChanged(QString)),this,SLOT(linkSpeedSelectionChanged(QString)));
338 338 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(sourceLogicalAddressChanged(QString)),this,SLOT(sourceLogicalAddressChanged(QString)));
339 339 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(rmapAddressChanged(QString)),this,SLOT(destinationAddressChanged(QString)));
340 340 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(destinationKeyChanged(QString)),this,SLOT(destinationKeyChanged(QString)));
341 341 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(rmapTimeoutChanged(QString)),this,SLOT(rmapTimeoutChanged(QString)));
342 342 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(brickModeChanged(bool)), this, SLOT(brickModeChanged(bool)));
343 343 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(timecodeFrequencyChange(QString)), this, SLOT(timecodeFrequencyChanged(QString)));
344 344 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(startSendingTimecode(bool)), this, SLOT(startSendingTimecodes(bool)));
345 345
346 346 this->brickSelectionChanged( ((StarDundeeGUI*)this->p_GUI)->getBrickSelection());
347 347 this->linkNumberSelectionChanged( ((StarDundeeGUI*)this->p_GUI)->getLinkNumberSelection());
348 348 this->linkSpeedSelectionChanged( ((StarDundeeGUI*)this->p_GUI)->getLinkSpeedSelection());
349 349 this->sourceLogicalAddressChanged(((StarDundeeGUI*)this->p_GUI)->getSourceAddress());
350 350 this->destinationAddressChanged( ((StarDundeeGUI*)this->p_GUI)->getDestinationAddress());
351 351 this->destinationKeyChanged( ((StarDundeeGUI*)this->p_GUI)->getDestinationKey());
352 352 this->rmapTimeoutChanged( ((StarDundeeGUI*)this->p_GUI)->getRmapTimeout());
353 353 this->brickModeChanged( ((StarDundeeGUI*)this->p_GUI)->isBrickSetAsAnInterface());
354 354
355 355 connect(this,SIGNAL(SelectBrick(int)), ((StarDundeeGUI*)this->p_GUI),SLOT(selectBrick(int)));
356 356 connect(this,SIGNAL(SelectLinkNumber(int)), ((StarDundeeGUI*)this->p_GUI),SLOT(selectLinkNumber(int)));
357 357 connect(this,SIGNAL(SelectLinkSpeed(int)), ((StarDundeeGUI*)this->p_GUI),SLOT(selectLinkSpeed(int)));
358 358 connect(this,SIGNAL(SetDestinationKey(QString)), ((StarDundeeGUI*)this->p_GUI),SLOT(setDestinationKey(QString)));
359 359 connect(this,SIGNAL(SetDestinationAddress(QString)),((StarDundeeGUI*)this->p_GUI),SLOT(setDestinationAddress(QString)));
360 360 connect(this,SIGNAL(SetSourceAddress(QString)), ((StarDundeeGUI*)this->p_GUI),SLOT(setSourceAddress(QString)));
361 361 connect(this,SIGNAL(SetRmapTimeout(QString)), ((StarDundeeGUI*)this->p_GUI),SLOT(setRmapTimeout(QString)));
362 362 connect(this,SIGNAL(GetAvailableBrickCount()), ((StarDundeeGUI*)this->p_GUI),SLOT(getAvailableBrickCount()));
363 363 connect(this,SIGNAL(GetNbPacketsTransmittedToSpw()),((StarDundeeGUI*)this->p_GUI),SLOT(getNbPacketsTransmittedToSpw()));
364 364 connect(this,SIGNAL(GetNbCCSDSPacketsTransmittedToSpw()),
365 365 ((StarDundeeGUI*)this->p_GUI),SLOT(getNbCCSDSPacketsTransmittedToSpw()));
366 366 connect(this,SIGNAL(SetBrickAsAnInterface(bool)), ((StarDundeeGUI*)this->p_GUI),SLOT(setBrickAsAnInterface(bool)));
367 367 connect(this,SIGNAL(SetBrickAsARouter(bool)), ((StarDundeeGUI*)this->p_GUI),SLOT(setBrickAsARouter(bool)));
368 368 connect(this,SIGNAL(BytesReceivedFromSpw(uint)), ((StarDundeeGUI*)this->p_GUI),SLOT(updateNbReceivedBytesFromSpw(uint)));
369 369 connect(this,SIGNAL(BytesTransmittedToSpw(uint)), ((StarDundeeGUI*)this->p_GUI),SLOT(updateNbTransmittedBytesToSpw(uint)));
370 370 connect(this,SIGNAL(CCSDSPacketTransmittedToSpw()), ((StarDundeeGUI*)this->p_GUI),SLOT(updateCCSDSPacketTransmittedToSpw()));
371 371 connect(this,SIGNAL(SetTimecodeFrequency(double)), ((StarDundeeGUI*)this->p_GUI),SLOT(setTimecodeFrequency(double)));
372 372 connect(this,SIGNAL(StartSendingTimecodes(bool)), ((StarDundeeGUI*)this->p_GUI),SLOT(setStartSendingTimecodes(bool)));
373 373
374 374 connect(this,SIGNAL(SendOneTimecode(unsigned char)),this->manager, SLOT(sendOneTimecode(unsigned char)));
375 375 connect(this,SIGNAL(GetLinkNumber()), this->manager, SLOT(getLinkNumber()));
376 376 }
377 377
378 378 void stardundeeSPW_USB::sendPacketComingFromTCPServer(char *packet, int size)
379 379 {
380 380 char* data;
381 381 int i;
382 382
383 383 data = (char *) malloc( size + 5 );
384 384
385 385 data[0] = this->manager->linkNumber;
386 386 data[1] = this->manager->destinationLogicalAddress; // target logical address
387 387 data[2] = SPW_PROTO_ID_CCSDS; // protocol identifier
388 388 data[3] = 0x00; // reserved
389 389 data[4] = 0x00; // user application
390 390
391 391 for ( i=0; i<size; i++ )
392 392 {
393 393 data[i+5] = packet[i];
394 394 }
395 395
396 396 this->manager->sendPacket( data, size + 5);
397 397
398 398 free(data);
399 399 free(packet);
400 400 }
401 401
402 402 stardundeeSPW_USB_Manager::stardundeeSPW_USB_Manager(socexplorerplugin *plugin, QObject *parent)
403 403 :QThread((QObject*)parent)
404 404 {
405 405 this->RMAPtimeout = 2000;
406 406 this->handleMutex = new QMutex(QMutex::NonRecursive);
407 407 // this->handleMutex = new QMutex(QMutex::Recursive);
408 408 this->RMAP_AnswersSem = new QSemaphore(0);
409 409 this->RMAP_AnswersMtx=new QMutex(QMutex::Recursive);
410 410 this->RMAP_pending_transaction_IDsMtx=new QMutex(QMutex::Recursive);
411 411 this->plugin = plugin;
412 412 connected = false;
413 413 // TODO remove this crap!
414 414 this->initDialog();
415 415 // this->moveToThread(this);
416 416 }
417 417
418 418 stardundeeSPW_USB_Manager::~stardundeeSPW_USB_Manager()
419 419 {
420 420 this->terminate();
421 421 while (!this->isFinished()) {
422 422 this->usleep(1000);
423 423 }
424 424 }
425 425
426 426 void stardundeeSPW_USB_Manager::run()
427 427 {
428 428 USB_SPACEWIRE_PACKET_PROPERTIES properties;
429 429 USB_SPACEWIRE_ID pIdentifier=NULL;
430 430 USB_SPACEWIRE_STATUS stat;
431 431 SocExplorerEngine::message(this->plugin,"Starting Startdundee USB pooling thread",1);
432 432 char buffer[(RMAP_MAX_XFER_SIZE*4)+50];
433 433 while (!this->isInterruptionRequested())
434 434 {
435 435 if(this->connected)
436 436 {
437 437 this->handleMutex->lock();
438 438 SocExplorerEngine::message(this->plugin,"Looking for new RMAP packets",4);
439 439 if(USBSpaceWire_WaitOnReadPacketAvailable(hDevice,0.01))
440 440 {
441 441 SocExplorerEngine::message(this->plugin,"Got packet",2);
442 442 stat = USBSpaceWire_ReadPackets(hDevice, buffer, (RMAP_MAX_XFER_SIZE*4)+50,1, 1, &properties, &pIdentifier);
443 443 if (stat == TRANSFER_SUCCESS)
444 444 {
445 445 if(USBSpaceWire_GetReadTrafficType(&properties, 0) ==SPACEWIRE_TRAFFIC_PACKET)
446 446 {
447 447 SocExplorerEngine::message(this->plugin,"It's a SPW packet",2);
448 448 if(USBSpaceWire_GetReadEOPStatus(&properties, 0)== SPACEWIRE_USB_EOP)
449 449 {
450 450 SocExplorerEngine::message(this->plugin,"Got end of packet",2);
451 451 emit bytesReceivedFromSpw( properties.len );
452 452 if(buffer[1]==(char)SPW_PROTO_ID_RMAP) //RMAP packet
453 453 {
454 454 RMAP_Answer* packet;
455 455 SocExplorerEngine::message(this->plugin,"Got RMAP packet",2);
456 456 SocExplorerEngine::message(this->plugin,QString("Rmap packet size %1").arg(properties.len),2);
457 457 char* packetbuffer = (char*)malloc(properties.len);
458 458 memcpy(packetbuffer,buffer,properties.len);
459 459 USBSpaceWire_FreeRead(hDevice, pIdentifier);
460 460 pIdentifier = NULL;
461 461 this->handleMutex->unlock();
462 462 if(properties.len==8)
463 463 {
464 464 packet=new RMAP_Answer(RMAP_get_transactionID(buffer),packetbuffer,properties.len);
465 465 }
466 466 else
467 467 {
468 468 packet=new RMAP_Answer(RMAP_get_transactionID(buffer+1),packetbuffer,properties.len);
469 469 }
470 470 RMAP_AnswersMtx->lock();
471 471 RMAP_Answers.append(packet);
472 472 RMAP_AnswersMtx->unlock();
473 473 RMAP_AnswersSem->release();
474 474 }
475 475 else //any non-rmap packet will be pushed to the network
476 476 {
477 477 char* packetbuffer = (char*)malloc(properties.len);
478 478 memcpy(packetbuffer,buffer,properties.len);
479 479 emit emitPacket(packetbuffer,properties.len);
480 480 USBSpaceWire_FreeRead(hDevice, pIdentifier);
481 481 this->handleMutex->unlock();
482 482 SocExplorerEngine::message(this->plugin,"Got SPW packet",2);
483 483 }
484 484 }
485 485 else
486 486 {
487 487 SocExplorerEngine::message(this->plugin,"No EOP received",2);
488 488 this->handleMutex->unlock();
489 489 }
490 490 }
491 491
492 492 }
493 493 else
494 494 {
495 495 USBSpaceWire_FreeRead(hDevice, pIdentifier);
496 496 this->handleMutex->unlock();
497 497 }
498 498 }
499 499 else
500 500 {
501 501 USBSpaceWire_FreeRead(hDevice, pIdentifier);
502 502 this->handleMutex->unlock();
503 503 }
504 504 }
505 505 else
506 506 {
507 507 //do some sanity checks!
508 508 int list = USBSpaceWire_ListDevices();
509 509 if(this->brickList!=list)
510 510 {
511 511 this->brickList = list;
512 512 emit updateAvailableBrickCount(this->brickList);
513 513 }
514 514 usleep(RMAPtimeout/2);
515 515 }
516 516 usleep(1000);
517 517 }
518 518 SocExplorerEngine::message(this->plugin,"Exiting Startdundee USB pooling thread",1);
519 519 }
520 520
521 521 bool stardundeeSPW_USB_Manager::connectBridge()
522 522 {
523 523 bool ret;
524 524
525 525 if (this->interfaceMode == BRICK_IS_SET_AS_AN_INTERFACE)
526 526 {
527 527 ret = connectBridgeAsInterface();
528 528 }
529 529 else if (this->interfaceMode == BRICK_IS_SET_AS_A_ROUTER)
530 530 {
531 531 ret = connectBridgeAsRouter();
532 532 }
533 533 else
534 534 {
535 535 ret = false;
536 536 }
537 537
538 538 return ret;
539 539 }
540 540
541 541 bool stardundeeSPW_USB_Manager::connectBridgeAsInterface()
542 542 {
543 543 this->handleMutex->lock();
544 544 int status;
545 545 U32 statusControl;
546 546 this->connected = false;
547 547 if (!USBSpaceWire_Open(&hDevice, this->selectedBrick)) // Open the USB device
548 548 {
549 549 SocExplorerEngine::message(this->plugin,"stardundee *** Open *** ERROR: USBSpaceWire_Open(&hDevice, 0))",0);
550 550 this->handleMutex->unlock();
551 551 return false;
552 552 }
553 553 SocExplorerEngine::message(this->plugin,"stardundee *** Open *** USBSpaceWire_Open successful",0);
554 554
555 555 USBSpaceWire_EnableNetworkMode(hDevice, 0); // deactivate the network mode
556 556 CFGSpaceWire_EnableRMAP(1); // Enable the use of RMAP for the StarDundee brick configuration
557 557 CFGSpaceWire_SetRMAPDestinationKey(0x20); // Set the destination key expected by STAR-Dundee devices
558 558
559 559 // Set the path and return path to the device
560 560 CFGSpaceWire_StackClear();
561 561 CFGSpaceWire_AddrStackPush(0);
562 562 CFGSpaceWire_AddrStackPush(254);
563 563 CFGSpaceWire_RetAddrStackPush(254);
564 564 // set the base transmit rate to 100 MHz
565 565 status = CFGSpaceWire_SetBrickBaseTransmitRate( hDevice, CFG_BRK_CLK_100_MHZ, CFG_BRK_DVDR_1, 0xff);
566 566 if (status != CFG_TRANSFER_SUCCESS)
567 567 {
568 568 SocExplorerEngine::message(this->plugin,"ERROR CFGSpaceWire_SetBrickBaseTransmitRate",1);
569 569 this->handleMutex->unlock();
570 570 return false;
571 571 }
572 572 else
573 573 {
574 574 SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_SetBrickBaseTransmitRate, base rate = 100 MHz",1);
575 575 }
576 576
577 577 // read the link status
578 578 if (CFGSpaceWire_GetLinkStatusControl(hDevice, this->linkNumber, &statusControl) != CFG_TRANSFER_SUCCESS)
579 579 {
580 580 SocExplorerEngine::message(this->plugin,"Could not read link status control for link " + QString::number(this->linkNumber),1);
581 581 this->handleMutex->unlock();
582 582 return false;
583 583 }
584 584 else
585 585 {
586 586 SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_GetLinkStatusControl of link " + QString::number(this->linkNumber),1);
587 587
588 588 // Set the link status control register properties
589 589 CFGSpaceWire_LSEnableAutoStart(&statusControl, 1);
590 590 CFGSpaceWire_LSEnableStart(&statusControl, 1);
591 591 CFGSpaceWire_LSEnableDisabled(&statusControl, 0);
592 592 CFGSpaceWire_LSEnableTristate(&statusControl, 0);
593 593 CFGSpaceWire_LSSetOperatingSpeed(&statusControl, 9); // sets the link speed to ( 100 MHz / (9+1) ) = 10 MHz
594 594
595 595 // Set the link status control register
596 596 if (CFGSpaceWire_SetLinkStatusControl(hDevice, this->linkNumber, statusControl) != CFG_TRANSFER_SUCCESS)
597 597 {
598 598 SocExplorerEngine::message(this->plugin,"Could not set the link status control for link " + QString::number(this->linkNumber),1);
599 599 this->handleMutex->unlock();
600 600 return false;
601 601 }
602 602 else
603 603 {
604 604 SocExplorerEngine::message(this->plugin,"Set the link status control for link " + QString::number(this->linkNumber),1);
605 605 }
606 606 }
607 607
608 608 if (CFGSpaceWire_SetAsInterface(hDevice, 1, 0) != CFG_TRANSFER_SUCCESS)
609 609 {
610 610 SocExplorerEngine::message(this->plugin,"Could not set the device to be an interface",1);
611 611 this->handleMutex->unlock();
612 612 return false;
613 613 }
614 614 else
615 615 {
616 616 SocExplorerEngine::message(this->plugin,"Device set to be an interface",1);
617 617 }
618 618
619 619 USBSpaceWire_RegisterReceiveOnAllPorts(hDevice); // Register to receive on all ports
620 620 USBSpaceWire_ClearEndpoints(hDevice); // clear the USB endpoints
621 621 USBSpaceWire_SetTimeout(hDevice,1.0);
622 622 this->handleMutex->unlock();
623 623 SocExplorerEngine::message(this->plugin,"The driver's current send buffer size is " + QString::number(USBSpaceWire_GetDriverSendBufferSize(hDevice)) + " bytes",1);
624 624 SocExplorerEngine::message(this->plugin,"The driver's current read buffer size is " + QString::number(USBSpaceWire_GetDriverReadBufferSize(hDevice)) + " bytes",1);
625 625 SocExplorerEngine::message(this->plugin,"USBSpaceWire_IsReadThrottling is " + QString::number(USBSpaceWire_IsReadThrottling(hDevice)),1);
626 626 this->connected = true;
627 627 return true;
628 628 }
629 629
630 630 bool stardundeeSPW_USB_Manager::connectBridgeAsRouter()
631 631 {
632 632 // QMutexLocker mlock(&this->handleMutex);
633 633 this->handleMutex->lock();
634 634 int status;
635 635 U32 statusControl;
636 636 unsigned int linkStatus1;
637 637 unsigned int linkStatus2;
638 638 unsigned char linkNumber;
639 639 unsigned char deviceIsAnInterface;
640 640
641 641 if (!USBSpaceWire_Open(&hDevice, this->selectedBrick)) // Open the USB device
642 642 {
643 643 SocExplorerEngine::message(this->plugin,"stardundee *** Open *** ERROR: USBSpaceWire_Open(&hDevice, 0))");
644 644 this->handleMutex->unlock();
645 645 return false;
646 646 }
647 647 SocExplorerEngine::message(this->plugin,"stardundee *** Open *** USBSpaceWire_Open successful, device number: "
648 648 + QString::number(this->selectedBrick));
649 649
650 650 USBSpaceWire_EnableNetworkMode(hDevice, 0); // deactivate the network mode
651 651 CFGSpaceWire_EnableRMAP(1); // Enable the use of RMAP for the StarDundee brick configuration
652 652 CFGSpaceWire_SetRMAPDestinationKey(0x20); // Set the destination key expected by STAR-Dundee devices
653 653
654 654 // Set the path and return path to the device
655 655 // This affects just the operations performed by the Configuration Library and does not affect the packets
656 656 // sent and received using the driver API.
657 657 CFGSpaceWire_StackClear();
658 658 CFGSpaceWire_AddrStackPush(0);
659 659 CFGSpaceWire_AddrStackPush(254);
660 660 CFGSpaceWire_RetAddrStackPush(254);
661 661
662 662 // set the base transmit rate to 100 MHz
663 663 status = CFGSpaceWire_SetBrickBaseTransmitRate( hDevice, CFG_BRK_CLK_100_MHZ, CFG_BRK_DVDR_1, 0xff);
664 664 if (status != CFG_TRANSFER_SUCCESS)
665 665 {
666 666 SocExplorerEngine::message(this->plugin,"ERROR CFGSpaceWire_SetBrickBaseTransmitRate");
667 667 }
668 668 else SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_SetBrickBaseTransmitRate, base rate = 100 MHz");
669 669
670 670 //*********************
671 671 // LINK 1 CONFIGURATION
672 672 linkNumber = 1;
673 673 if (CFGSpaceWire_GetLinkStatusControl(hDevice, linkNumber, &statusControl) != CFG_TRANSFER_SUCCESS)
674 674 SocExplorerEngine::message(this->plugin,"Could not read link status control for link " + QString::number(linkNumber));
675 675 else
676 676 {
677 677 SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_GetLinkStatusControl of link " + QString::number(linkNumber));
678 678
679 679 // Set the link status control register properties
680 680 CFGSpaceWire_LSEnableAutoStart(&statusControl, 1);
681 681 CFGSpaceWire_LSEnableStart(&statusControl, 1);
682 682 CFGSpaceWire_LSEnableDisabled(&statusControl, 0);
683 683 CFGSpaceWire_LSEnableTristate(&statusControl, 0);
684 684 CFGSpaceWire_LSSetOperatingSpeed(&statusControl, 9); // sets the link speed to ( 100 MHz / (9+1) ) = 10 MHz
685 685
686 686 // Set the link status control register
687 687 if (CFGSpaceWire_SetLinkStatusControl(hDevice, linkNumber, statusControl) != CFG_TRANSFER_SUCCESS)
688 688 SocExplorerEngine::message(this->plugin,"Could not set the link status control for link " + QString::number(linkNumber));
689 689 else
690 690 SocExplorerEngine::message(this->plugin,"link status control for link " + QString::number(0x01) + " is set");
691 691 }
692 692
693 693 //*********************
694 694 // LINK 2 CONFIGURATION
695 695 linkNumber = 2;
696 696 if (CFGSpaceWire_GetLinkStatusControl(hDevice, linkNumber, &statusControl) != CFG_TRANSFER_SUCCESS)
697 697 SocExplorerEngine::message(this->plugin,"Could not read link status control for link " + QString::number(linkNumber));
698 698 else
699 699 {
700 700 SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_GetLinkStatusControl of link " + QString::number(linkNumber));
701 701
702 702 // Set the link status control register properties
703 703 CFGSpaceWire_LSEnableAutoStart(&statusControl, 1);
704 704 CFGSpaceWire_LSEnableStart(&statusControl, 1);
705 705 CFGSpaceWire_LSEnableDisabled(&statusControl, 0);
706 706 CFGSpaceWire_LSEnableTristate(&statusControl, 0);
707 707 CFGSpaceWire_LSSetOperatingSpeed(&statusControl, 9); // sets the link speed to ( 100 MHz / (9+1) ) = 10 MHz
708 708
709 709 // Set the link status control register
710 710 if (CFGSpaceWire_SetLinkStatusControl(hDevice, linkNumber, statusControl) != CFG_TRANSFER_SUCCESS)
711 711 SocExplorerEngine::message(this->plugin,"Could not set the link status control for link " + QString::number(linkNumber));
712 712 else
713 713 SocExplorerEngine::message(this->plugin,"link status control for link " + QString::number(linkNumber) + " is set");
714 714 }
715 715
716 716 //***************************
717 717 // SET THE DEVICE AS A ROUTER
718 718 deviceIsAnInterface = 0; // 0 = router, 1 = interface
719 719 if (CFGSpaceWire_SetAsInterface(hDevice, deviceIsAnInterface, 0) != CFG_TRANSFER_SUCCESS)
720 720 SocExplorerEngine::message(this->plugin,"Could not set the device to be an interface");
721 721 else
722 722 SocExplorerEngine::message(this->plugin,"Device is an interface: " + QString::number(deviceIsAnInterface) + " (1 => true, 0 => false)");
723 723
724 724 setRoutingTableEntry(0xfe, 0x02, 0); // [0010] => route 0xfe on port 1
725 725 setRoutingTableEntry(32 , 0x08, 0); // [1000] => route 32 on port 3
726 726
727 727 USBSpaceWire_RegisterReceiveOnAllPorts(hDevice); // Register to receive on port 1 only
728 728 USBSpaceWire_ClearEndpoints(hDevice); // clear the USB endpoints
729 729
730 730 SocExplorerEngine::message(this->plugin,"The driver's current send buffer size is " + QString::number(USBSpaceWire_GetDriverSendBufferSize(hDevice)) + " bytes");
731 731 SocExplorerEngine::message(this->plugin,"The driver's current read buffer size is " + QString::number(USBSpaceWire_GetDriverReadBufferSize(hDevice)) + " bytes");
732 732 SocExplorerEngine::message(this->plugin,"USBSpaceWire_IsReadThrottling is " + QString::number(USBSpaceWire_IsReadThrottling(hDevice)));
733 733
734 734 //************
735 735 // test Link 1 and Link 2
736 736 linkStatus1 = getLinkStatus(0x01);
737 737 linkStatus2 = getLinkStatus(0x02);
738 738 this->handleMutex->unlock();
739 739
740 740 if ((linkStatus1==1) || (linkStatus2==1))
741 741 {
742 742 initializeTimecodeGeneration();
743 743 this->connected=true;
744 744 return true;
745 745 }
746 746 else
747 747 {
748 748 statusLink1->setText("Link 1 status code: " + QString::number(linkStatus1));
749 749 statusLink2->setText("Link 2 status code: " + QString::number(linkStatus2));
750 750 starDundeeStatusQueryDialog->exec();
751 751 this->connected = false;
752 752 return false;
753 753 }
754 754 }
755 755
756 756 void stardundeeSPW_USB_Manager::initDialog( void )
757 757 {
758 758 // STAR DUNDEE STATUS QUERY DIALOG
759 759 starDundeeStatusQueryDialog = new QDialog;
760 760 starDundeeStatusQueryDialogLayout = new QGridLayout;
761 761 starDundeeStatusQueryDialogLabel = new QLabel(tr("SpaceWire links state"));
762 762 starDundeeStatusQueryContinueButton = new QPushButton(tr("Continue"));
763 763 starDundeeStatusQueryRetryButton = new QPushButton(tr("Retry"));
764 764 starDundeeStatusQueryAbortButton = new QPushButton(tr("Abort"));
765 765 statusLink1 = new QLabel(tr("Link 1 status code: -"));
766 766 statusLink2 = new QLabel(tr("Link 2 status code: -"));
767 767
768 768 starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryDialogLabel, 0, 0, 1, 2);
769 769 starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryContinueButton, 1, 0, 0);
770 770 starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryRetryButton, 1, 1, 0);
771 771 starDundeeStatusQueryDialogLayout->addWidget(starDundeeStatusQueryAbortButton, 1, 2, 0);
772 772 starDundeeStatusQueryDialogLayout->addWidget(statusLink1, 2, 0, 0);
773 773 starDundeeStatusQueryDialogLayout->addWidget(statusLink2, 3, 0, 0);
774 774 starDundeeStatusQueryDialog->setLayout(starDundeeStatusQueryDialogLayout);
775 775 }
776 776
777 777 unsigned char stardundeeSPW_USB_Manager::setRoutingTableEntry(int tableEntry, U32 dwOutputPorts, char bDelHead)
778 778 {
779 779 U32 routingTableEntry;
780 780 // SET THE ROUTING TABLE ENTRY FOR LOGICAL ADDRESSING, TARGET entryNumber
781 781 if (CFGSpaceWire_ClearRoutingTableEntry(hDevice, tableEntry) != CFG_TRANSFER_SUCCESS)
782 782 {
783 783 SocExplorerEngine::message(this->plugin,"Could not clear routing table entry " + QString::number(tableEntry));
784 784 }
785 785 // Build the routing table entry
786 786 CFGSpaceWire_RTBuildRoutingTableEntry(&routingTableEntry,
787 787 dwOutputPorts, // route out of port dwOutputPorts
788 788 bDelHead, // header deletion is enabled [1] or disabled [0]
789 789 0); // priority normal
790 790 // Set the routing table entry for logical address tableEntry
791 791 if (CFGSpaceWire_SetRoutingTableEntry(hDevice, tableEntry, routingTableEntry) != CFG_TRANSFER_SUCCESS)
792 792 {
793 793 SocExplorerEngine::message(this->plugin,"Could not set routing table entry [" + QString::number(tableEntry) + "]");
794 794 }
795 795 else SocExplorerEngine::message(this->plugin,"Routing table entry [" + QString::number(tableEntry) + "] set" );
796 796 return 1;
797 797 }
798 798
799 799 unsigned int stardundeeSPW_USB_Manager::getRoutingTableEntry(int tableEntry)
800 800 {
801 801 U32 routingTableEntry, outputPorts;
802 802 char enabled, delHead, priority;
803 803 int portNum;
804 804
805 805 SocExplorerEngine::message(this->plugin,"GetRoutingTableEntry [" + QString::number(tableEntry) + "]");
806 806 // Read the routing table entry
807 807 if (CFGSpaceWire_GetRoutingTableEntry(hDevice, tableEntry, &routingTableEntry) != CFG_TRANSFER_SUCCESS)
808 808 {
809 809 SocExplorerEngine::message(this->plugin,"Could not read routing table entry [" + QString::number(tableEntry) + "]");
810 810 }
811 811 else
812 812 {
813 813 // Display the routing table entry properties
814 814 CFGSpaceWire_RTIsEnabled(routingTableEntry, &enabled);
815 815 CFGSpaceWire_RTIsDelHead(routingTableEntry, &delHead);
816 816 CFGSpaceWire_RTIsPriority(routingTableEntry, &priority);
817 817 CFGSpaceWire_RTGetOutputPorts(routingTableEntry, &outputPorts);
818 818 SocExplorerEngine::message(this->plugin,"CFGSpaceWire_RTIsEnabled : " + QString::number(enabled));
819 819 SocExplorerEngine::message(this->plugin,"CFGSpaceWire_RTIsDelHead : " + QString::number(delHead));
820 820 SocExplorerEngine::message(this->plugin,"CFGSpaceWire_RTIsPriority : " + QString::number(priority));
821 821 SocExplorerEngine::message(this->plugin,"CFGSpaceWire_RTGetOutputPorts : ");
822 822 for (portNum = 0; portNum < 32; portNum++)
823 823 {
824 824 if (outputPorts & (1 << portNum))
825 825 {
826 826 SocExplorerEngine::message(this->plugin,QString::number(portNum));
827 827 }
828 828 }
829 829 }
830 830
831 831 return 1;
832 832 }
833 833
834 834 void stardundeeSPW_USB_Manager::initializeTimecodeGeneration()
835 835 {
836 836 U32 dwTickEnableStatus;
837 837 U32 rtr_clk_freq;
838 838
839 839 // (1) RESET
840 840 if (!USBSpaceWire_TC_Reset(hDevice))
841 841 SocExplorerEngine::message(this->plugin,"ERR *** in Open *** Could not reset timecodes\n");
842 842
843 843 // (2) Clear the tick enable register
844 844 if (CFGSpaceWire_SetTickEnableStatus(hDevice, 6) != CFG_TRANSFER_SUCCESS)
845 845 SocExplorerEngine::message(this->plugin,"Could not clear the tick enable register");
846 846 else
847 847 SocExplorerEngine::message(this->plugin,"Cleared the tick enable register");
848 848
849 849 // (3) get the tick status
850 850 CFGSpaceWire_GetTickEnableStatus(hDevice, &dwTickEnableStatus);
851 851 SocExplorerEngine::message(this->plugin,"OK *** in Open *** CFGSpaceWire_GetTickEnableStatus, code is " + QString::number(dwTickEnableStatus, 2));
852 852
853 853 // (4) enable external timecode selection
854 854 if(!USBSpaceWire_TC_EnableExternalTimecodeSelection(hDevice,0))
855 855 SocExplorerEngine::message(this->plugin,"ERR *** disable external timecode selection");
856 856
857 857 rtr_clk_freq = USBSpaceWire_TC_GetClockFrequency(hDevice);
858 858
859 859 SocExplorerEngine::message(this->plugin,"clock frequency = " + QString::number(rtr_clk_freq) );
860 860
861 861 //**************************************************
862 862 // auto _ tick _ freq = rtr _ clk _ freq / freqCount
863 863 if (!USBSpaceWire_TC_SetAutoTickInFrequency(hDevice, rtr_clk_freq) )
864 864 SocExplorerEngine::message(this->plugin,"Could not set the tick-in frequency");
865 865 }
866 866
867 867 unsigned int stardundeeSPW_USB_Manager::getLinkStatus(unsigned char link)
868 868 {
869 869 U32 statusControl, errorStatus, portType;
870 870 U32 linkStatus, operatingSpeed, outputPortConnection;
871 871 char isLinkRunning, isAutoStart, isStart, isDisabled, isTristate;
872 872
873 873 // Read the link status control register
874 874 if (CFGSpaceWire_GetLinkStatusControl(hDevice, link, &statusControl) != CFG_TRANSFER_SUCCESS)
875 875 {
876 876 SocExplorerEngine::message(this->plugin,"Could not read link status control for link" + QString::number(link));
877 877 }
878 878 else
879 879 {
880 880 // Display the link status control register properties
881 881 CFGSpaceWire_LSPortType(statusControl, &portType);
882 882 if (portType == CFG_CONFIGURATION_PORT)
883 883 {
884 884 CFGSpaceWire_LSConfigErrorStatus(statusControl, &errorStatus);
885 885 }
886 886 else if (portType == CFG_SPACEWIRE_EXTERNAL_PORT)
887 887 {
888 888 CFGSpaceWire_LSExternalErrorStatus(statusControl, &errorStatus);
889 889 }
890 890 else
891 891 {
892 892 CFGSpaceWire_LSErrorStatus(statusControl, &errorStatus);
893 893 }
894 894 CFGSpaceWire_LSLinkState(statusControl, &linkStatus);
895 895 CFGSpaceWire_LSIsLinkRunning(statusControl, &isLinkRunning);
896 896 CFGSpaceWire_LSIsAutoStart(statusControl, &isAutoStart);
897 897 CFGSpaceWire_LSIsStart(statusControl, &isStart);
898 898 CFGSpaceWire_LSIsDisabled(statusControl, &isDisabled);
899 899 CFGSpaceWire_LSIsTristate(statusControl, &isTristate);
900 900 CFGSpaceWire_LSOperatingSpeed(statusControl, &operatingSpeed);
901 901 CFGSpaceWire_LSOutputPortConnection(statusControl, &outputPortConnection);
902 902 }
903 903 SocExplorerEngine::message(this->plugin,"status of link " + QString::number(link)
904 904 +" is " + dwLinkStatusQString[linkStatus]);
905 905 if (linkStatus == 5)
906 906 {
907 907 return 1;
908 908 }
909 909 else return 0;
910 910 }
911 911
912 912 bool stardundeeSPW_USB_Manager::disconnectBridge()
913 913 {
914 914 this->handleMutex->lock();
915 915 USBSpaceWire_Close(hDevice); // Close the device
916 916 SocExplorerEngine::message(this->plugin,"stardundee *** Close *** USBSpaceWire_Close, device: " + QString::number(0),0);
917 917 USBSpaceWire_UnregisterReceiveOnAllPorts(hDevice); // Stop receiving on all ports
918 918 this->handleMutex->unlock();
919 919 this->RMAP_pending_transaction_IDsMtx->lock();
920 920 this->RMAP_pending_transaction_IDs.clear();
921 921 this->RMAP_pending_transaction_IDsMtx->unlock();
922 922 this->RMAP_AnswersMtx->lock();
923 923 this->RMAP_Answers.clear();
924 924 this->RMAP_AnswersMtx->unlock();
925 925 this->RMAP_AnswersSem->acquire(this->RMAP_AnswersSem->available());
926 926 return true;
927 927 }
928 928
929 929 int stardundeeSPW_USB_Manager::getRMAPtransactionID()
930 930 {
931 931 this->RMAP_pending_transaction_IDsMtx->lock();
932 932 int ID=0;
933 933 bool found=true;
934 934 while(ID<511)
935 935 {
936 936 for(int i=0;i<RMAP_pending_transaction_IDs.count();i++)
937 937 {
938 938 if(RMAP_pending_transaction_IDs[i]==ID)found=false;
939 939 }
940 940 if(found==true)break;
941 941 ID++;
942 942 found = true;
943 943 }
944 944 if(found)
945 945 {
946 946 RMAP_pending_transaction_IDs.append(ID);
947 947 }
948 948 this->RMAP_pending_transaction_IDsMtx->unlock();
949 949 return ID;
950 950 }
951 951
952 952 int stardundeeSPW_USB_Manager::getRMAPanswer(int transactionID, char **buffer)
953 953 {
954 954 QTime timeout;
955 955 *buffer=NULL;
956 956 int count=0;
957 957 SocExplorerEngine::message(this->plugin,"Looking for RMAP answer",2);
958 958 timeout.start();
959 959 while (*buffer==NULL)
960 960 {
961 961 this->RMAP_AnswersMtx->lock();
962 962 SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_Answers stack",2);
963 963 SocExplorerEngine::message(this->plugin,QString("%1 packet(s) available in RMAP_Answers stack").arg(RMAP_Answers.count()),2);
964 964 for(int i=0;i<RMAP_Answers.count();i++)
965 965 {
966 966 SocExplorerEngine::message(this->plugin,QString("Packet %1 ID=%2").arg(i).arg(RMAP_Answers[i]->transactionID),2);
967 967 if(RMAP_Answers[i]->transactionID==transactionID)
968 968 {
969 969 this->RMAP_pending_transaction_IDsMtx->lock();
970 970 SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_pending_transaction_ID stack",2);
971 971 for(int j=0;j<RMAP_pending_transaction_IDs.count();j++)
972 972 {
973 973 if(RMAP_pending_transaction_IDs[j]==transactionID)
974 974 {
975 975 RMAP_pending_transaction_IDs.removeAt(j);
976 976 }
977 977 }
978 978 this->RMAP_pending_transaction_IDsMtx->unlock();
979 979 *buffer = RMAP_Answers[i]->data;
980 980 count = RMAP_Answers[i]->len;
981 981 RMAP_Answer* tmp=RMAP_Answers[i];
982 982 RMAP_Answers.removeAt(i);
983 983 delete tmp;
984 984 }
985 985 }
986 986 this->RMAP_AnswersMtx->unlock();
987 987 //if no answer found in the stack wait until a new packet is pushed
988 988 SocExplorerEngine::message(this->plugin,"waiting until a new packet is pushed",2);
989 989 if(*buffer==NULL)
990 990 {
991 991 while (0==this->RMAP_AnswersSem->available())
992 992 {
993 993 SocExplorerEngine::message(this->plugin,QString("this->RMAP_AnswersSem->available() = %1").arg(this->RMAP_AnswersSem->available()),2);
994 994 if(timeout.elapsed()>=RMAPtimeout)
995 995 {
996 996 SocExplorerEngine::message(this->plugin,"Timeout reached giving up!",2);
997 997 return -1;
998 998 }
999 999 usleep(1000);
1000 1000 }
1001 1001 this->RMAP_AnswersSem->acquire();
1002 1002 }
1003 1003 }
1004 1004 return count;
1005 1005 }
1006 1006
1007 1007 bool stardundeeSPW_USB_Manager::sendPacket(char *packet, int size)
1008 1008 {
1009 1009 char protocoleIdentifier;
1010 1010 USB_SPACEWIRE_STATUS result=TRANSFER_ERROR_NOT_FOUND;
1011 1011 USB_SPACEWIRE_ID pIdentifier;
1012 1012 SocExplorerEngine::message(this->plugin,"Sending SPW packet",2);
1013 1013 this->handleMutex->lock();
1014 1014 result = USBSpaceWire_SendPacket(hDevice,packet,size,1, &pIdentifier);
1015 1015 USBSpaceWire_FreeSend(hDevice, pIdentifier);
1016 1016 this->handleMutex->unlock();
1017 1017 if (result != TRANSFER_SUCCESS)
1018 1018 {
1019 1019 SocExplorerEngine::message(this->plugin,"ERR sending the READ command ",2);
1020 1020 return false;
1021 1021 }
1022 1022 else
1023 1023 {
1024 1024 emit bytesTransmittedToSpw( size-1 ); // -1 is for removing the first bytes added to the packet to route to the right link
1025 1025 // read the protocole identifier
1026 1026 protocoleIdentifier = packet[2];
1027 1027 if (protocoleIdentifier == SPW_PROTO_ID_CCSDS)
1028 1028 emit ccsdsPacketTransmittedToSpw();
1029 1029
1030 1030 SocExplorerEngine::message(this->plugin,"Packet sent",2);
1031 1031 }
1032 // this->handleMutex->unlock();
1033 1032 return true;
1034 1033 }
1035 1034
1036 1035 void stardundeeSPW_USB_Manager::pushRmapPacket(char *packet, int len)
1037 1036 {
1038 1037 char* packetbuffer = (char*)malloc(len);
1039 1038 memcpy(packetbuffer,packet,len);
1040 1039 RMAP_Answer* RMPAPpacket=new RMAP_Answer(RMAP_get_transactionID(packetbuffer+1),packetbuffer,len);
1041 1040 RMAP_AnswersMtx->lock();
1042 1041 RMAP_Answers.append(RMPAPpacket);
1043 1042 RMAP_AnswersMtx->unlock();
1044 1043 }
1045 1044
1046 1045 void stardundeeSPW_USB_Manager::sendTimecodePeriodically( bool onOff )
1047 1046 {
1047 this->handleMutex->lock();
1048 1048 if (onOff == true)
1049 1049 {
1050 1050 if (!USBSpaceWire_TC_EnableAutoTickIn(hDevice, 1, 1))
1051 1051 SocExplorerEngine::message(this->plugin,"Could not enable auto tick-in");
1052 1052 }
1053 1053 else
1054 1054 {
1055 1055 if (!USBSpaceWire_TC_EnableAutoTickIn(hDevice, 0, 0))
1056 1056 SocExplorerEngine::message(this->plugin,"Could not disable auto tick-in");
1057 1057 }
1058 this->handleMutex->unlock();
1058 1059 }
1059 1060
1060 1061 int stardundeeSPW_USB_Manager::getLinkNumber( void )
1061 1062 {
1062 1063 return this->linkNumber;
1063 1064 }
1064 1065
1065 1066 void stardundeeSPW_USB_Manager::setTimecodeFrequency(double requestedFrequency)
1066 1067 {
1067 1068 U32 rtr_clk_freq=0;
1068 1069 U32 freqCount=0;
1069 1070 double freqCountInDouble=0.0;
1070 1071 double currentFrequency=0.0;
1071 1072
1073 this->handleMutex->lock();
1072 1074 rtr_clk_freq = USBSpaceWire_TC_GetClockFrequency(hDevice);
1073 1075 freqCountInDouble = ((double) rtr_clk_freq) / requestedFrequency;
1074 1076 freqCount = (unsigned int) freqCountInDouble;
1075 1077
1076 1078 currentFrequency = ((double) rtr_clk_freq) / ((double) freqCount);
1077 1079
1078 1080 //**************************************************
1079 1081 // auto _ tick _ freq = rtr _ clk _ freq / freqCount
1080 1082 if (!USBSpaceWire_TC_SetAutoTickInFrequency(hDevice, freqCount) )
1081 1083 SocExplorerEngine::message(this->plugin,"Could not set the tick-in frequency");
1082 1084 else
1083 1085 SocExplorerEngine::message(this->plugin,"tick frequency set to " + QString::number(currentFrequency) +" Hz"
1084 1086 + " (freqCount set to " + QString::number(freqCount) + ")" );
1087 this->handleMutex->unlock();
1085 1088 }
1086 1089
1087 1090 void stardundeeSPW_USB_Manager::sendOneTimecode( unsigned char nTimein )
1088 1091 {
1092 this->handleMutex->lock();
1089 1093 // enable external timecode selection
1090 1094 if(!USBSpaceWire_TC_EnableExternalTimecodeSelection(hDevice,1))
1091 1095 SocExplorerEngine::message(this->plugin,"sendOneTimecode *** ERR *** enable external timecode selection");
1092 1096
1093 1097 if (!USBSpaceWire_TC_PerformTickIn( hDevice, nTimein) )
1094 1098 SocExplorerEngine::message( this->plugin,"sendOneTimecode *** ERR *** Could not send the requested timecode: " + QString::number(nTimein) );
1095 1099 else
1096 1100 SocExplorerEngine::message( this->plugin,"sendOneTimecode *** OK *** timecode sent " + QString::number(nTimein) );
1097 1101
1098 1102 // disable external timecode selection
1099 1103 if(!USBSpaceWire_TC_EnableExternalTimecodeSelection(hDevice,0))
1100 1104 SocExplorerEngine::message(this->plugin,"sendOneTimecode *** ERR *** disable external timecode selection");
1105 this->handleMutex->unlock();
1101 1106 }
1102 1107
1103 1108
General Comments 0
You need to be logged in to leave comments. Login now