##// END OF EJS Templates
Now RMAP write uses Transaction ID and waits for ack.
Jeandet Alexis -
r16:66782ba1cf13 default
parent child
Show More
@@ -1,142 +1,142
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 "spwplugin.h"
24 24 #include "stardundeespw_usb.h"
25 25 #include <socexplorerproxy.h>
26 26 #include "spwpywrapper.h"
27 27 spwplugin::spwplugin(QWidget *parent):socexplorerplugin(parent,false)
28 28 {
29 29 Q_UNUSED(parent)
30 30 this->bridge = NULL;
31 31 this->scanDone = false;
32 32 this->pyObject = new spwPyWrapper(this);
33 33 this->mainGroupBox = new QGroupBox("SpaceWire Plugin Configuration",this);
34 34 this->bridgeSelector = new QComboBox(this);
35 this->mainLayout = new QGridLayout(this);
35 this->mainLayout = new QGridLayout(this->mainGroupBox);
36 36 this->mainLayout->addWidget(new QLabel("Select SpaceWire bridge",this),0,0,1,1,Qt::AlignCenter);
37 37 this->mainLayout->addWidget(this->bridgeSelector,0,1,1,1);
38 38 this->mainGroupBox->setLayout(this->mainLayout);
39 39 this->setWidget(this->mainGroupBox);
40 40 this->bridgeSelector->addItem("none");
41 41 this->bridgeSelector->addItem("STAR-Dundee Spw USB Brick");
42 42 connect(this->bridgeSelector,SIGNAL(currentIndexChanged(QString)),this,SLOT(bridgeSelectionChanged(QString)));
43 43 connect(((spwPyWrapper*)this->pyObject),SIGNAL(selectBridge(QString)),this,SLOT(selectBridge(QString)));
44 44 }
45 45
46 46
47 47 spwplugin::~spwplugin()
48 48 {
49 49
50 50 }
51 51
52 52
53 53
54 54 unsigned int spwplugin::Read(unsigned int *Value,unsigned int count,unsigned int address)
55 55 {
56 56 if(Connected)
57 57 {
58 58 return bridge->Read(Value,count,address);
59 59 }
60 60 return 0;
61 61 }
62 62
63 63 void spwplugin::bridgeSelectionChanged(const QString &text)
64 64 {
65 65 printf("test");
66 66 if(text=="none")
67 67 {
68 68 if(this->bridge!=NULL)
69 69 {
70 70 this->mainLayout->removeWidget(this->bridge->getGUI());
71 71 this->disconnect(this,SLOT(setConnected(bool)));
72 72 delete this->bridge;
73 73 this->bridge= NULL;
74 74 }
75 75 }
76 76 if(text=="STAR-Dundee Spw USB Brick")
77 77 {
78 78 if(this->bridge!=NULL)
79 79 {
80 80 this->mainLayout->removeWidget(this->bridge->getGUI());
81 81 this->disconnect(this,SLOT(setConnected(bool)));
82 82 delete this->bridge;
83 83 }
84 84 this->bridge = new stardundeeSPW_USB(this);
85 85 this->mainLayout->addWidget(this->bridge->getGUI(),1,0,1,2);
86 86 connect(this->bridge,SIGNAL(setConnected(bool)),this,SLOT(setConnected(bool)));
87 87 connect(((spwPyWrapper*)this->pyObject),SIGNAL(StarDundeeSelectBrick(int)),((stardundeeSPW_USB*)bridge),SIGNAL(SelectBrick(int)));
88 88 connect(((spwPyWrapper*)this->pyObject),SIGNAL(StarDundeeSelectLinkNumber(int)),((stardundeeSPW_USB*)bridge),SIGNAL(SelectLinkNumber(int)));
89 89 connect(((spwPyWrapper*)this->pyObject),SIGNAL(StarDundeeSelectLinkSpeed(int)),((stardundeeSPW_USB*)bridge),SIGNAL(SelectLinkSpeed(int)));
90 90 connect(((spwPyWrapper*)this->pyObject),SIGNAL(StarDundeeSetDestinationKey(QString)),((stardundeeSPW_USB*)bridge),SIGNAL(SetDestinationKey(QString)));
91 91 connect(((spwPyWrapper*)this->pyObject),SIGNAL(StarDundeeSetRmapAddress(QString)),((stardundeeSPW_USB*)bridge),SIGNAL(SetRmapAddress(QString)));
92 92 connect(((spwPyWrapper*)this->pyObject),SIGNAL(StarDundeeSetRmapKey(QString)),((stardundeeSPW_USB*)bridge),SIGNAL(SetRmapKey(QString)));
93 93 connect(((spwPyWrapper*)this->pyObject),SIGNAL(StarDundeeSetRmapTimeout(QString)),((stardundeeSPW_USB*)bridge),SIGNAL(SetRmapTimeout(QString)));
94 94 connect(((spwPyWrapper*)this->pyObject),SIGNAL(connectBridge()),((stardundeeSPW_USB*)bridge),SLOT(connectBridge()));
95 95 connect(((spwPyWrapper*)this->pyObject),SIGNAL(disconnectBridge()),((stardundeeSPW_USB*)bridge),SLOT(disconnectBridge()));
96 96 }
97 97
98 98 }
99 99
100 100 void spwplugin::selectBridge(const QString &text)
101 101 {
102 102
103 103 if(text=="none")
104 104 {
105 105 this->bridgeSelector->setCurrentIndex(0);
106 106 }
107 107 if(text=="STAR-Dundee Spw USB Brick")
108 108 {
109 109 this->bridgeSelector->setCurrentIndex(1);
110 110 }
111 111 }
112 112
113 113 void spwplugin::setConnected(bool connected)
114 114 {
115 115 this->bridgeSelector->setDisabled(connected);
116 116 this->Connected = connected;
117 117 emit activateSig(connected);
118 118 if(!this->scanDone)
119 119 {
120 120 socexplorerproxy::loadChildSysDriver(this,"AMBA_PLUGIN");
121 121 this->scanDone=true;
122 122 }
123 123 }
124 124
125 125
126 126
127 127 unsigned int spwplugin::Write(unsigned int *Value,unsigned int count, unsigned int address)
128 128 {
129 129 if(Connected)
130 130 {
131 131 return bridge->Write(Value,count,address);
132 132 }
133 133 return 0;
134 134 }
135 135
136 136
137 137
138 138
139 139
140 140
141 141
142 142
@@ -1,636 +1,643
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 <socexplorerengine.h>
25 25 #include <qhexedit.h>
26 26
27 27 stardundeeSPW_USB::stardundeeSPW_USB(socexplorerplugin *parent) :
28 28 abstractSpwBridge(parent)
29 29 {
30 30 Q_UNUSED(parent)
31 31 this->manager = new stardundeeSPW_USB_Manager(parent,this);
32 32 makeGUI(parent);
33 33 this->manager->start();
34 34 }
35 35
36 36 stardundeeSPW_USB::~stardundeeSPW_USB()
37 37 {
38 38 this->manager->requestInterruption();
39 39 delete this->p_GUI;
40 40 }
41 41
42 42 void stardundeeSPW_USB::toggleBridgeConnection()
43 43 {
44 44 if(this->plugin->isConnected())
45 45 {
46 46 this->disconnectBridge();
47 47 }
48 48 else
49 49 {
50 50 this->connectBridge();
51 51 }
52 52 }
53 53
54 54 bool stardundeeSPW_USB::connectBridge()
55 55 {
56 56 if(this->manager->connectBridge())
57 57 {
58 58 ((StarDundeeGUI*)this->p_GUI)->lock(true);
59 59 emit setConnected(true);
60 60 return true;
61 61 }
62 62 return false;
63 63 }
64 64
65 65 bool stardundeeSPW_USB::disconnectBridge()
66 66 {
67 67 if(this->manager->disconnectBridge())
68 68 {
69 69 ((StarDundeeGUI*)this->p_GUI)->lock(false);
70 70 emit setConnected(false);
71 71 return true;
72 72 }
73 73 return false;
74 74 }
75 75
76 76
77 77 int stardundeeSPW_USB::pushRMAPPacket(char *packet, int size)
78 78 {
79 79 return this->manager->sendPacket(packet,size);
80 80 }
81 81
82 82 unsigned int stardundeeSPW_USB::Write(unsigned int *Value, unsigned int count, unsigned int address)
83 83 {
84 84 char writeBuffer[RMAP_WRITE_PACKET_MIN_SZ((RMAP_MAX_XFER_SIZE*4))+1];
85 char *RMAPAckBuff;
85 86 writeBuffer[0]=this->manager->linkNumber;//Link number
86 87 int transactionID = 0;
87 88 int written=0;
88 89 SocExplorerEngine::message(this->plugin,"Enter Write function",2);
89 90 QProgressBar* progress=NULL;
90 91 SocExplorerAutoProgressBar autopb;
91 92 if(count>RMAP_MAX_XFER_SIZE)
92 93 {
93 94 progress= SocExplorerEngine::getProgressBar("Writing on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
94 95 autopb.setProgressBar(progress);
95 96 }
96 97 //Quite stupide loop, I guess that I always get the number of byte I asked for!
97 98 while(count>=RMAP_MAX_XFER_SIZE)
98 99 {
99 100 for(int i=0;i<(RMAP_MAX_XFER_SIZE);i++)
100 101 {
101 102 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
102 103 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
103 104 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
104 105 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+4] = (char)(((unsigned int)Value[i+written])&0xFF);
105 106 }
107 transactionID=manager->getRMAPtransactionID();
108 SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
106 109 RMAP_build_tx_request_header(this->manager->rmapAddress,this->manager->rmapKey,1,transactionID,address+(written*4),RMAP_MAX_XFER_SIZE*4,writeBuffer+1);
107 110 manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(RMAP_MAX_XFER_SIZE*4)+1);
111 manager->getRMAPanswer(transactionID,&RMAPAckBuff);
112 free(RMAPAckBuff);
108 113 written+=RMAP_MAX_XFER_SIZE;
109 114 count-=RMAP_MAX_XFER_SIZE;
110 115 progress->setValue(written);
111 116 qApp->processEvents();
112 117 }
113 118 if(count>0)
114 119 {
115 120 for(int i=0;i<((int)count);i++)
116 121 {
117 122 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+1] = (char)(((unsigned int)Value[i+written]>>24)&0xFF);
118 123 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+2] = (char)(((unsigned int)Value[i+written]>>16)&0xFF);
119 124 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+3] = (char)(((unsigned int)Value[i+written]>>8)&0xFF);
120 125 writeBuffer[RMAP_WRITE_HEADER_MIN_SZ+(i*4)+4] = (char)(((unsigned int)Value[i+written])&0xFF);
121 126 }
127 transactionID=manager->getRMAPtransactionID();
128 SocExplorerEngine::message(this->plugin,QString("Sending Write request with ID=%1").arg(transactionID),2);
122 129 RMAP_build_tx_request_header(this->manager->rmapAddress,this->manager->rmapKey,1,transactionID,address+(written*4),count*4,writeBuffer+1);
123 130 manager->sendPacket(writeBuffer,RMAP_WRITE_PACKET_MIN_SZ(count*4) +1);
131 manager->getRMAPanswer(transactionID,&RMAPAckBuff);
132 free(RMAPAckBuff);
124 133 written+=count;
125 134 if(progress!=NULL)
126 135 {
127 136 progress->setValue(written);
128 137 qApp->processEvents();
129 138 }
130 139 }
131 140 return written;
132 141 }
133 142
134 143 unsigned int stardundeeSPW_USB::Read(unsigned int *Value, unsigned int count, unsigned int address)
135 144 {
136 145 char requestBuffer[RMAP_READ_HEADER_MIN_SZ+1];
137 146 char* RMAP_AnswerBuffer;
138 147 requestBuffer[0]=this->manager->linkNumber;//Link number
139 148 int transactionID = 0;
140 149 int read=0;
141 150 QProgressBar* progress=NULL;
142 151 SocExplorerAutoProgressBar autopb;
143 152 if(count>RMAP_MAX_XFER_SIZE)
144 153 {
145 154 progress= SocExplorerEngine::getProgressBar("Reading on SPW @0x"+QString::number(address,16)+" %v of "+QString::number(count)+" words ",count);
146 155 autopb.setProgressBar(progress);
147 156 }
148 157 SocExplorerEngine::message(this->plugin,QString("Enter read function, count=%1, RMAP_MAX_XFER_SIZE=%2").arg(count).arg(RMAP_MAX_XFER_SIZE),2);
149 158
150 159 //Quite stupide loop, I guess that I always get the number of byte I asked for!
151 160 while((int)count>=(int)RMAP_MAX_XFER_SIZE)
152 161 {
153 162 transactionID = manager->getRMAPtransactionID();
154 163 SocExplorerEngine::message(this->plugin,QString("New transactionID:%1").arg(transactionID),2);
155 164 RMAP_build_rx_request_header(this->manager->rmapAddress,this->manager->rmapKey,1,transactionID,address+(read*4),RMAP_MAX_XFER_SIZE*4,requestBuffer+1);
156 165 manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ+1);
157 166 int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
158 167 if(len==-1)
159 168 {
160 169 this->toggleBridgeConnection();
161 170 return 0;
162 171 }
163 172 for(int i=0;i<((len-13)/4);i++)
164 173 {
165 174 Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
166 175 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
167 176 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
168 177 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
169 178 }
170 179 free(RMAP_AnswerBuffer);
171 180 read+=RMAP_MAX_XFER_SIZE;
172 181 count-=RMAP_MAX_XFER_SIZE;
173 182 progress->setValue(read);
174 183 qApp->processEvents();
175 184 }
176 185 if((int)count>0)
177 186 {
178 187 transactionID = manager->getRMAPtransactionID();
179 188 SocExplorerEngine::message(this->plugin,QString("New transactionID: %1").arg(transactionID),2);
180 189 SocExplorerEngine::message(this->plugin,QString("Building request with:"),2);
181 190 SocExplorerEngine::message(this->plugin,QString("Address = %1").arg(address+(read*4),8,16),2);
182 191 SocExplorerEngine::message(this->plugin,QString("Size = %1").arg(count*4),2);
183 192 SocExplorerEngine::message(this->plugin,QString("Size + 13 = %1").arg((count*4)+13),2);
184 193 RMAP_build_rx_request_header(this->manager->rmapAddress,this->manager->rmapKey,1,transactionID,address+(read*4),count*4,requestBuffer+1);
185 194 manager->sendPacket(requestBuffer,RMAP_READ_HEADER_MIN_SZ+1);
186 195 int len=manager->getRMAPanswer(transactionID,&RMAP_AnswerBuffer);
187 196 if(len==-1)
188 197 {
189 198 this->toggleBridgeConnection();
190 199 return 0;
191 200 }
192 201 for(int i=0;i<((len-13)/4);i++)
193 202 {
194 203 Value[read+i] = 0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+12]);
195 204 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+13]));
196 205 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+14]));
197 206 Value[read+i] = (Value[read+i]<<8) + (0x0FF & ((unsigned int)RMAP_AnswerBuffer[(4*i)+15]));
198 207 }
199 208 free(RMAP_AnswerBuffer);
200 209 read+=count;
201 210 if(progress!=NULL)
202 211 {
203 212 progress->setValue(read);
204 213 qApp->processEvents();
205 214 }
206 215 }
207 216 return read;
208 217 }
209 218
210 219 void stardundeeSPW_USB::brickSelectionChanged(int brickIndex)
211 220 {
212 221 this->manager->selectedBrick = brickIndex-1;
213 222 SocExplorerEngine::message(plugin,QString("Changing brick index: %1").arg(manager->selectedBrick),1);
214 223 }
215 224
216 225 void stardundeeSPW_USB::linkNumberSelectionChanged(int linkIndex)
217 226 {
218 227 this->manager->linkNumber = linkIndex + 1;
219 228 SocExplorerEngine::message(plugin,QString("Changing Link Number: %1").arg(manager->linkNumber),1);
220 229 }
221 230
222 231 void stardundeeSPW_USB::linkSpeedSelectionChanged(const QString &linkSpeed)
223 232 {
224 233 this->manager->linkSpeed = linkSpeed.toInt();
225 234
226 235 SocExplorerEngine::message(plugin,QString("Changing Link Speed: %1").arg(manager->linkSpeed),1);
227 236 }
228 237
229 238 void stardundeeSPW_USB::destinationKeyChanged(const QString &destKey)
230 239 {
231 240 this->manager->destinationKey = destKey.toInt();
232 241 SocExplorerEngine::message(plugin,QString("Changing Destination Key: %1").arg(manager->destinationKey),1);
233 242 }
234 243
235 244 void stardundeeSPW_USB::rmapAddressChanged(const QString &rmapaddress)
236 245 {
237 246 this->manager->rmapAddress = rmapaddress.toInt();
238 247 SocExplorerEngine::message(plugin,QString("Changing RMAP address: %1").arg(manager->rmapAddress),1);
239 248 }
240 249
241 250 void stardundeeSPW_USB::rmapKeyChanged(const QString &key)
242 251 {
243 252 this->manager->rmapKey = key.toInt();
244 253 SocExplorerEngine::message(plugin,QString("Changing RMAP Key: %1").arg(manager->rmapKey),1);
245 254 }
246 255
247 256 void stardundeeSPW_USB::rmapTimeoutChanged(const QString &timeout)
248 257 {
249 258 int tim=timeout.toInt();
250 259 if(tim<50)
251 260 {
252 261 tim = 50;
253 262 ((StarDundeeGUI*)this->p_GUI)->setRmapTimeout(QString("%1").arg(tim));
254 263 }
255 264 this->manager->RMAPtimeout = tim;
256 265 SocExplorerEngine::message(plugin,QString("Changing RMAP Timeout: %1").arg(manager->RMAPtimeout),1);
257 266 }
258 267
259 268
260 269 void stardundeeSPW_USB::makeGUI(socexplorerplugin *parent)
261 270 {
262 271 this->p_GUI = new StarDundeeGUI();
263 // this->mainLayout = new QGridLayout(this->p_GUI);
272 // this->mainLayout = new QGridLayout(this->p_GUI);
264 273 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(connectClicked()),this,SLOT(toggleBridgeConnection()));
265 274 connect(this->manager,SIGNAL(updateAvailableBrickCount(int)),((StarDundeeGUI*)this->p_GUI),SLOT(updateAvailableBrickCount(int)));
266 275 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(brickSelectionChanged(int)),this,SLOT(brickSelectionChanged(int)));
267 276 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(linkNumberSelectionChanged(int)),this,SLOT(linkNumberSelectionChanged(int)));
268 277 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(linkSpeedSelectionChanged(QString)),this,SLOT(linkSpeedSelectionChanged(QString)));
269 278 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(destinationKeyChanged(QString)),this,SLOT(destinationKeyChanged(QString)));
270 279 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(rmapAddressChanged(QString)),this,SLOT(rmapAddressChanged(QString)));
271 280 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(rmapKeyChanged(QString)),this,SLOT(rmapKeyChanged(QString)));
272 281 connect(((StarDundeeGUI*)this->p_GUI),SIGNAL(rmapTimeoutChanged(QString)),this,SLOT(rmapTimeoutChanged(QString)));
273 282
274 283 this->brickSelectionChanged(((StarDundeeGUI*)this->p_GUI)->getBrickSelection());
275 284 this->linkNumberSelectionChanged(((StarDundeeGUI*)this->p_GUI)->getLinkNumberSelection());
276 285 this->linkSpeedSelectionChanged(((StarDundeeGUI*)this->p_GUI)->getLinkSpeedSelection());
277 286 this->destinationKeyChanged(((StarDundeeGUI*)this->p_GUI)->getDestinationKey());
278 287 this->rmapAddressChanged(((StarDundeeGUI*)this->p_GUI)->getRmapAddress());
279 288 this->rmapKeyChanged(((StarDundeeGUI*)this->p_GUI)->getRmapKey());
280 289 this->rmapTimeoutChanged(((StarDundeeGUI*)this->p_GUI)->getRmapTimeout());
281 290
282 291 connect(this,SIGNAL(SelectBrick(int)),((StarDundeeGUI*)this->p_GUI),SLOT(selectBrick(int)));
283 292 connect(this,SIGNAL(SelectLinkNumber(int)),((StarDundeeGUI*)this->p_GUI),SLOT(selectLinkNumber(int)));
284 293 connect(this,SIGNAL(SelectLinkSpeed(int)),((StarDundeeGUI*)this->p_GUI),SLOT(selectLinkSpeed(int)));
285 294 connect(this,SIGNAL(SetDestinationKey(QString)),((StarDundeeGUI*)this->p_GUI),SLOT(setDestinationKey(QString)));
286 295 connect(this,SIGNAL(SetRmapAddress(QString)),((StarDundeeGUI*)this->p_GUI),SLOT(setRmapAddress(QString)));
287 296 connect(this,SIGNAL(SetRmapKey(QString)),((StarDundeeGUI*)this->p_GUI),SLOT(setRmapKey(QString)));
288 297 connect(this,SIGNAL(SetRmapTimeout(QString)),((StarDundeeGUI*)this->p_GUI),SLOT(setRmapTimeout(QString)));
289 298
290 299 }
291 300
292 301 stardundeeSPW_USB_Manager::stardundeeSPW_USB_Manager(socexplorerplugin *plugin, QObject *parent)
293 302 :QThread((QObject*)parent)
294 303 {
295 304 this->RMAPtimeout = 2000;
296 305 this->handleMutex = new QMutex(QMutex::NonRecursive);
297 306 this->RMAP_AnswersSem = new QSemaphore(0);
298 307 this->RMAP_AnswersMtx=new QMutex(QMutex::Recursive);
299 308 this->RMAP_pending_transaction_IDsMtx=new QMutex(QMutex::Recursive);
300 309 this->plugin = plugin;
301 310 connected = false;
302 311 this->moveToThread(this);
303 312 }
304 313
305 314 stardundeeSPW_USB_Manager::~stardundeeSPW_USB_Manager()
306 315 {
307 316 this->terminate();
308 317 while (!this->isFinished()) {
309 318 this->usleep(1000);
310 319 }
311 320 }
312 321
313 322
314 323 void stardundeeSPW_USB_Manager::run()
315 324 {
316 325 USB_SPACEWIRE_PACKET_PROPERTIES properties;
317 326 USB_SPACEWIRE_ID pIdentifier=NULL;
318 327 USB_SPACEWIRE_STATUS stat;
319 328 SocExplorerEngine::message(this->plugin,"Starting Startdundee USB pooling thread",1);
320 329 char buffer[(RMAP_MAX_XFER_SIZE*4)+50];
321 330 while (!this->isInterruptionRequested())
322 331 {
323 332 if(this->connected)
324 333 {
325 334 handleMutex->lock();
326 335 SocExplorerEngine::message(this->plugin,"Looking for new RMAP packets",4);
327 336 if(USBSpaceWire_WaitOnReadPacketAvailable(hDevice,0.01))
328 337 {
329 338 SocExplorerEngine::message(this->plugin,"Got packet",2);
330 339 stat = USBSpaceWire_ReadPackets(hDevice, buffer, (RMAP_MAX_XFER_SIZE*4)+50,1, 1, &properties, &pIdentifier);
331 340 if (stat == TRANSFER_SUCCESS)
332 341 {
333 342 if(USBSpaceWire_GetReadTrafficType(&properties, 0) ==SPACEWIRE_TRAFFIC_PACKET)
334 343 {
335 344 SocExplorerEngine::message(this->plugin,"It's a SPW packet",2);
336 345 if(USBSpaceWire_GetReadEOPStatus(&properties, 0)== SPACEWIRE_USB_EOP)
337 346 {
338 347 SocExplorerEngine::message(this->plugin,"Got end of packet",2);
339 348 if(buffer[1]==(char)SPW_PROTO_ID_RMAP) //RMAP packet
340 349 {
350 RMAP_Answer* packet;
341 351 SocExplorerEngine::message(this->plugin,"Got RMAP packet",2);
342 352 SocExplorerEngine::message(this->plugin,QString("Rmap packet size %1").arg(properties.len),2);
343 if(properties.len>8)
353 char* packetbuffer = (char*)malloc(properties.len);
354 memcpy(packetbuffer,buffer,properties.len);
355 USBSpaceWire_FreeRead(hDevice, pIdentifier);
356 pIdentifier = NULL;
357 handleMutex->unlock();
358 if(properties.len==8)
344 359 {
345 char* packetbuffer = (char*)malloc(properties.len);
346 memcpy(packetbuffer,buffer,properties.len);
347 USBSpaceWire_FreeRead(hDevice, pIdentifier);
348 pIdentifier = NULL;
349 handleMutex->unlock();
350 RMAP_Answer* packet=new RMAP_Answer(RMAP_get_transactionID(buffer+1),packetbuffer,properties.len);
351 RMAP_AnswersMtx->lock();
352 RMAP_Answers.append(packet);
353 RMAP_AnswersMtx->unlock();
354 RMAP_AnswersSem->release();
355
360 packet=new RMAP_Answer(RMAP_get_transactionID(buffer),packetbuffer,properties.len);
356 361 }
357 else //it's a RMAP write response
362 else
358 363 {
359 USBSpaceWire_FreeRead(hDevice, pIdentifier);
360 pIdentifier = NULL;
361 handleMutex->unlock();
364 packet=new RMAP_Answer(RMAP_get_transactionID(buffer+1),packetbuffer,properties.len);
362 365 }
363
366 RMAP_AnswersMtx->lock();
367 RMAP_Answers.append(packet);
368 RMAP_AnswersMtx->unlock();
369 RMAP_AnswersSem->release();
364 370 }
365 371 else //any non-rmap packet will be pushed to the network
366 372 {
367 373 USBSpaceWire_FreeRead(hDevice, pIdentifier);
368 374 handleMutex->unlock();
369 375 SocExplorerEngine::message(this->plugin,"Got SPW packet",2);
370 376 }
371 377 }
372 378 else
373 379 {
374 380 SocExplorerEngine::message(this->plugin,"No EOP received",2);
375 381 }
376 382 }
377 383
378 384 }
379 385 else
380 386 {
381 387 USBSpaceWire_FreeRead(hDevice, pIdentifier);
382 388 handleMutex->unlock();
383 389 }
384 390 }
385 391 else
386 392 {
387 393 USBSpaceWire_FreeRead(hDevice, pIdentifier);
388 394 handleMutex->unlock();
389 395 }
390 396 }
391 397 else
392 398 {
393 399 //do some sanity checks!
394 400 int list = USBSpaceWire_ListDevices();
395 401 if(this->brickList!=list)
396 402 {
397 403 this->brickList = list;
398 404 emit updateAvailableBrickCount(this->brickList);
399 405 }
400 406 usleep(RMAPtimeout/2);
401 407 }
402 408 usleep(1000);
403 409 }
404 410 SocExplorerEngine::message(this->plugin,"Exiting Startdundee USB pooling thread",1);
405 411 }
406 412
407 413 bool stardundeeSPW_USB_Manager::connectBridge()
408 414 {
409 415 QMutexLocker mlock(this->handleMutex);
410 416 int status;
411 417 U32 statusControl;
412 418 this->connected = false;
413 419 if (!USBSpaceWire_Open(&hDevice, this->selectedBrick)) // Open the USB device
414 420 {
415 421 SocExplorerEngine::message(this->plugin,"stardundee *** Open *** ERROR: USBSpaceWire_Open(&hDevice, 0))",0);
416 422 return false;
417 423 }
418 424 SocExplorerEngine::message(this->plugin,"stardundee *** Open *** USBSpaceWire_Open successful",0);
419 425
420 426 USBSpaceWire_EnableNetworkMode(hDevice, 0); // deactivate the network mode
421 427 CFGSpaceWire_EnableRMAP(1); // Enable the use of RMAP for the StarDundee brick configuration
422 428 CFGSpaceWire_SetRMAPDestinationKey(0x20); // Set the destination key expected by STAR-Dundee devices
423 429
424 430 // Set the path and return path to the device
425 431 CFGSpaceWire_StackClear();
426 432 CFGSpaceWire_AddrStackPush(0);
427 433 CFGSpaceWire_AddrStackPush(254);
428 434 CFGSpaceWire_RetAddrStackPush(254);
429 435 // set the base transmit rate to 100 MHz
430 436 status = CFGSpaceWire_SetBrickBaseTransmitRate( hDevice, CFG_BRK_CLK_100_MHZ, CFG_BRK_DVDR_1, 0xff);
431 437 if (status != CFG_TRANSFER_SUCCESS)
432 438 {
433 439 SocExplorerEngine::message(this->plugin,"ERROR CFGSpaceWire_SetBrickBaseTransmitRate",1);
434 440 return false;
435 441 }
436 442 else
437 443 {
438 444 SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_SetBrickBaseTransmitRate, base rate = 100 MHz",1);
439 445 }
440 446
441 447 // read the link status
442 448 if (CFGSpaceWire_GetLinkStatusControl(hDevice, this->linkNumber, &statusControl) != CFG_TRANSFER_SUCCESS)
443 449 {
444 450 SocExplorerEngine::message(this->plugin,"Could not read link status control for link " + QString::number(this->linkNumber),1);
445 451 return false;
446 452 }
447 453 else
448 454 {
449 455 SocExplorerEngine::message(this->plugin,"OK CFGSpaceWire_GetLinkStatusControl of link " + QString::number(this->linkNumber),1);
450 456
451 457 // Set the link status control register properties
452 458 CFGSpaceWire_LSEnableAutoStart(&statusControl, 1);
453 459 CFGSpaceWire_LSEnableStart(&statusControl, 1);
454 460 CFGSpaceWire_LSEnableDisabled(&statusControl, 0);
455 461 CFGSpaceWire_LSEnableTristate(&statusControl, 0);
456 462 CFGSpaceWire_LSSetOperatingSpeed(&statusControl, 9); // sets the link speed to ( 100 MHz / (9+1) ) = 10 MHz
457 463
458 464 // Set the link status control register
459 465 if (CFGSpaceWire_SetLinkStatusControl(hDevice, this->linkNumber, statusControl) != CFG_TRANSFER_SUCCESS)
460 466 {
461 467 SocExplorerEngine::message(this->plugin,"Could not set the link status control for link " + QString::number(this->linkNumber),1);
462 468 return false;
463 469 }
464 470 else
465 471 {
466 472 SocExplorerEngine::message(this->plugin,"Set the link status control for link " + QString::number(this->linkNumber),1);
467 473 }
468 474 }
469 475
470 476 if (CFGSpaceWire_SetAsInterface(hDevice, 1, 0) != CFG_TRANSFER_SUCCESS)
471 477 {
472 478 SocExplorerEngine::message(this->plugin,"Could not set the device to be an interface",1);
473 479 return false;
474 480 }
475 481 else
476 482 {
477 483 SocExplorerEngine::message(this->plugin,"Device set to be an interface",1);
478 484 }
479 485
480 486 USBSpaceWire_RegisterReceiveOnAllPorts(hDevice); // Register to receive on all ports
481 487 USBSpaceWire_ClearEndpoints(hDevice); // clear the USB endpoints
482 488 USBSpaceWire_SetTimeout(hDevice,1.0);
483 489 SocExplorerEngine::message(this->plugin,"The driver's current send buffer size is " + QString::number(USBSpaceWire_GetDriverSendBufferSize(hDevice)) + " bytes",1);
484 490 SocExplorerEngine::message(this->plugin,"The driver's current read buffer size is " + QString::number(USBSpaceWire_GetDriverReadBufferSize(hDevice)) + " bytes",1);
485 491 SocExplorerEngine::message(this->plugin,"USBSpaceWire_IsReadThrottling is " + QString::number(USBSpaceWire_IsReadThrottling(hDevice)),1);
486 492 this->connected = true;
487 493 return true;
488 494 }
489 495
490 496 bool stardundeeSPW_USB_Manager::disconnectBridge()
491 497 {
492 498 this->handleMutex->lock();
493 499 USBSpaceWire_Close(hDevice); // Close the device
494 500 SocExplorerEngine::message(this->plugin,"stardundee *** Close *** USBSpaceWire_Close, device: " + QString::number(0),0);
495 501 USBSpaceWire_UnregisterReceiveOnAllPorts(hDevice); // Stop receiving on all ports
496 502 this->handleMutex->unlock();
497 503 this->RMAP_pending_transaction_IDsMtx->lock();
498 504 this->RMAP_pending_transaction_IDs.clear();
499 505 this->RMAP_pending_transaction_IDsMtx->unlock();
500 506 this->RMAP_AnswersMtx->lock();
501 507 this->RMAP_Answers.clear();
502 508 this->RMAP_AnswersMtx->unlock();
503 509 this->RMAP_AnswersSem->acquire(this->RMAP_AnswersSem->available());
504 510 return true;
505 511 }
506 512
507 513 int stardundeeSPW_USB_Manager::getRMAPtransactionID()
508 514 {
509 515 this->RMAP_pending_transaction_IDsMtx->lock();
510 516 int ID=0;
511 517 bool found=true;
512 518 while(ID<511)
513 519 {
514 520 for(int i=0;i<RMAP_pending_transaction_IDs.count();i++)
515 521 {
516 522 if(RMAP_pending_transaction_IDs[i]==ID)found=false;
517 523 }
518 524 if(found==true)break;
519 525 ID++;
520 526 found = true;
521 527 }
522 528 if(found)
523 529 {
524 530 RMAP_pending_transaction_IDs.append(ID);
525 531 }
526 532 this->RMAP_pending_transaction_IDsMtx->unlock();
527 533 return ID;
528 534 }
529 535
530 536 int stardundeeSPW_USB_Manager::getRMAPanswer(int transactionID, char **buffer)
531 537 {
532 538 QTime timeout;
533 539 *buffer=NULL;
534 540 int count=0;
535 541 SocExplorerEngine::message(this->plugin,"Looking for RMAP answer",2);
536 542 timeout.start();
537 543 while (*buffer==NULL)
538 544 {
539 545 this->RMAP_AnswersMtx->lock();
540 546 SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_Answers stack",2);
541 SocExplorerEngine::message(this->plugin,QString("%2 packet(s) available in RMAP_Answers stack").arg(RMAP_Answers.count()),2);
547 SocExplorerEngine::message(this->plugin,QString("%1 packet(s) available in RMAP_Answers stack").arg(RMAP_Answers.count()),2);
542 548 for(int i=0;i<RMAP_Answers.count();i++)
543 549 {
550 SocExplorerEngine::message(this->plugin,QString("Packet %1 ID=%2").arg(i).arg(RMAP_Answers[i]->transactionID),2);
544 551 if(RMAP_Answers[i]->transactionID==transactionID)
545 552 {
546 553 this->RMAP_pending_transaction_IDsMtx->lock();
547 554 SocExplorerEngine::message(this->plugin,"Got exclusive access on RMAP_pending_transaction_ID stack",2);
548 555 for(int j=0;j<RMAP_pending_transaction_IDs.count();j++)
549 556 {
550 557 if(RMAP_pending_transaction_IDs[j]==transactionID)
551 558 {
552 559 RMAP_pending_transaction_IDs.removeAt(j);
553 560 }
554 561 }
555 562 this->RMAP_pending_transaction_IDsMtx->unlock();
556 563 *buffer = RMAP_Answers[i]->data;
557 564 count = RMAP_Answers[i]->len;
558 565 RMAP_Answer* tmp=RMAP_Answers[i];
559 566 RMAP_Answers.removeAt(i);
560 567 delete tmp;
561 568 }
562 569 }
563 570 this->RMAP_AnswersMtx->unlock();
564 571 //if no answer found in the stack wait until a new packet is pushed
565 572 SocExplorerEngine::message(this->plugin,"waiting until a new packet is pushed",2);
566 573 if(*buffer==NULL)
567 574 {
568 575 while (0==this->RMAP_AnswersSem->available())
569 576 {
570 577 SocExplorerEngine::message(this->plugin,QString("this->RMAP_AnswersSem->available() = %1").arg(this->RMAP_AnswersSem->available()),2);
571 578 if(timeout.elapsed()>=RMAPtimeout)
572 579 {
573 580 SocExplorerEngine::message(this->plugin,"Timeout reached giving up!",2);
574 581 return -1;
575 582 }
576 583 usleep(1000);
577 584 }
578 585 this->RMAP_AnswersSem->acquire();
579 586 }
580 587 }
581 588 return count;
582 589 }
583 590
584 591 bool stardundeeSPW_USB_Manager::sendPacket(char *packet, int size)
585 592 {
586 593 USB_SPACEWIRE_STATUS result;
587 594 USB_SPACEWIRE_ID pIdentifier;
588 595 SocExplorerEngine::message(this->plugin,"Sending SPW packet",2);
589 596 this->handleMutex->lock();
590 597 result = USBSpaceWire_SendPacket(hDevice,packet,size,1, &pIdentifier);
591 598 if (result != TRANSFER_SUCCESS)
592 599 {
593 600 SocExplorerEngine::message(this->plugin,"ERR sending the READ command ",2);
594 601 this->handleMutex->unlock();
595 602 return false;
596 603 }
597 604 else
598 605 {
599 606 SocExplorerEngine::message(this->plugin,"Packet sent",2);
600 607 USBSpaceWire_FreeSend(hDevice, pIdentifier);
601 608 }
602 609 this->handleMutex->unlock();
603 610 return true;
604 611 }
605 612
606 613 void stardundeeSPW_USB_Manager::pushRmapPacket(char *packet, int len)
607 614 {
608 615 char* packetbuffer = (char*)malloc(len);
609 616 memcpy(packetbuffer,packet,len);
610 617 RMAP_Answer* RMPAPpacket=new RMAP_Answer(RMAP_get_transactionID(packetbuffer+1),packetbuffer,len);
611 618 RMAP_AnswersMtx->lock();
612 619 RMAP_Answers.append(RMPAPpacket);
613 620 RMAP_AnswersMtx->unlock();
614 621 }
615 622
616 623
617 624
618 625
619 626
620 627
621 628
622 629
623 630
624 631
625 632
626 633
627 634
628 635
629 636
630 637
631 638
632 639
633 640
634 641
635 642
636 643
General Comments 0
You need to be logged in to leave comments. Login now