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