00001 #include "OtsUDPFirmwareCore.h"
00002
00003 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00004 #include "otsdaq-core/Macros/CoutMacros.h"
00005
00006
00007
00008
00009 #include <sys/socket.h>
00010 #include <netinet/in.h>
00011 #include <arpa/inet.h>
00012 #include <algorithm>
00013 #include <iostream>
00014 #include <cstdlib>
00015 #include <iomanip>
00016
00017
00018 using namespace ots;
00019
00021
00022
00023
00024 #define UDP_CORE_BLOCK_ADDRESS ((uint64_t)(0x1) << 32)
00025 #define ADDR_SELF_UPPER_IP (uint64_t)(0x0) //24
00026 #define ADDR_SELF_LOWER_IP (uint64_t)(0x1) //8
00027 #define ADDR_SELF_MAC (uint64_t)(0x2) //40
00028
00029 #define ADDR_CTRL_DEST_IP (uint64_t)(0x3) //32
00030 #define ADDR_CTRL_DEST_MAC (uint64_t)(0x4) //48
00031 #define ADDR_CTRL_DEST_PORT (uint64_t)(0x5) //16
00032
00033 #define ADDR_DATA_DEST_IP (uint64_t)(0x6) //32
00034 #define ADDR_DATA_DEST_MAC (uint64_t)(0x7) //48
00035 #define ADDR_DATA_DEST_PORT (uint64_t)(0x8) //16
00036
00037 #define ADDR_BURST_MODE (uint64_t)(0x9) //1
00038 #define ADDR_CTRL_RESOLVE_MAC (uint64_t)(0xA) //1
00039 #define ADDR_DATA_RESOLVE_MAC (uint64_t)(0xB) //1
00040 #define ADDR_SELF_VERSION (uint64_t)(0x64) //16 (read only)
00041 #define ADDR_SELF_RESET (uint64_t)(0xFFFFFFFF) //1 (write only)
00042
00043
00045
00046
00047 const uint8_t OtsUDPFirmwareCore::FIFO_ADDRESS_CMD_TYPE = (1 << 3);
00048
00049
00050 OtsUDPFirmwareCore::OtsUDPFirmwareCore(unsigned int version)
00051 : FrontEndFirmwareBase(version)
00052 {}
00053
00054
00055 OtsUDPFirmwareCore::~OtsUDPFirmwareCore(void)
00056 {}
00057
00058
00059 void OtsUDPFirmwareCore::init(void)
00060 {}
00061
00062
00063 std::string OtsUDPFirmwareCore::write(
00064 char* address, char* data)
00065 {
00066 std::string buffer;
00067 writeAdvanced(buffer,address,data);
00068 return buffer;
00069 }
00070
00071
00072 void OtsUDPFirmwareCore::write(
00073 std::string& buffer,char* address, char* data, bool clearBuffer)
00074 {
00075 writeAdvanced(buffer,address,data,1,0,clearBuffer);
00076 }
00077
00078
00079 void OtsUDPFirmwareCore::write(
00080 std::string& buffer,
00081 uint32_t address,
00082 uint32_t data,
00083 bool clearBuffer)
00084 {
00085 writeAdvanced(buffer,address,data,0,clearBuffer);
00086 }
00087
00088
00089 void OtsUDPFirmwareCore::write(
00090 std::string& buffer,
00091 uint64_t address,
00092 uint64_t data,
00093 bool clearBuffer)
00094 {
00095 writeAdvanced(buffer,address,data,0,clearBuffer);
00096 }
00097
00098
00099
00100
00101 void OtsUDPFirmwareCore::OtsUDPFirmwareCore::writeAdvanced(std::string& buffer,
00102 const char* address,
00103 const char* data,
00104 uint8_t size,
00105 uint8_t commandTypeOptions,
00106 bool clearBuffer)
00107 {
00108 if(size > 182)
00109 {
00110 __SS__ << "Invalid OtsUDPFirmwareCore::writeAdvanced size: " << size << std::endl;
00111 __COUT_ERR__ << "\n" << ss.str();
00112 __SS_THROW__;
00113 }
00114
00115 if(buffer.size() + 2 + 8 + 8*size > 2 + 8 + 8*182)
00116 {
00117 __SS__ << "Aborting. Buffer overflow attempt: " << buffer.size() << " + " <<
00118 2 + 8 + 8*size << " > " << 2 + 8 + 8*182 << std::endl;
00119 __COUT_ERR__ << "\n" << ss.str();
00120 __SS_THROW__;
00121 }
00122
00123 if(clearBuffer)
00124 buffer.resize(0);
00125
00126 unsigned int begin = buffer.length();
00127 buffer.resize(buffer.length() + 2 + 8 + 8*size, '\0');
00128
00129 buffer[begin + 0] = 1 | commandTypeOptions;
00130 buffer[begin + 1] = size;
00131
00132 std::copy_n(address,sizeof(uint64_t),&buffer[begin + 2]);
00133 for(uint8_t i=0;i<size;++i)
00134 std::copy_n((char *)&data[8*i],sizeof(uint64_t),&buffer[begin + 2 + 8 + 8*i]);
00135
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 }
00150
00151
00152
00153
00154 void OtsUDPFirmwareCore::OtsUDPFirmwareCore::writeAdvanced(std::string& buffer,
00155 const uint64_t& address,
00156 const char* data,
00157 uint8_t size,
00158 uint8_t commandTypeOptions,
00159 bool clearBuffer)
00160 {
00161 OtsUDPFirmwareCore::writeAdvanced(buffer,(char *)&address,data,size,commandTypeOptions,clearBuffer);
00162 }
00163
00164
00165 void OtsUDPFirmwareCore::OtsUDPFirmwareCore::writeAdvanced(std::string& buffer,
00166 const uint64_t& address,
00167 const uint64_t& data,
00168 uint8_t commandTypeOptions,
00169 bool clearBuffer)
00170 {
00171 OtsUDPFirmwareCore::writeAdvanced(buffer,(char *)&address,(char *)&data,1 ,commandTypeOptions,clearBuffer);
00172 }
00173
00174
00175 void OtsUDPFirmwareCore::OtsUDPFirmwareCore::writeAdvanced(std::string& buffer,
00176 const uint64_t& address,
00177 const std::vector<uint64_t>& data,
00178 uint8_t commandTypeOptions,
00179 bool clearBuffer)
00180 {
00181 OtsUDPFirmwareCore::writeAdvanced(buffer,(char *)&address,(char *)&data[0],data.size() ,commandTypeOptions,clearBuffer);
00182 }
00183
00184
00185 std::string OtsUDPFirmwareCore::read
00186 (char* address)
00187 {
00188 __COUT__ << "OTS pointer based read!! " << std::endl;
00189 std::string buffer;
00190 readAdvanced(buffer,address);
00191 return buffer;
00192 }
00193
00194
00195 void OtsUDPFirmwareCore::read
00196 (std::string& buffer, char* address, bool clearBuffer)
00197 {
00198 readAdvanced(buffer,address,1,0,clearBuffer);
00199 }
00200
00201
00202 void OtsUDPFirmwareCore::read
00203 (std::string& buffer, uint64_t address, bool clearBuffer)
00204 {
00205 readAdvanced(buffer,address,1,0,clearBuffer);
00206 }
00207
00208
00209 void OtsUDPFirmwareCore::read
00210 (std::string& buffer, uint32_t address, bool clearBuffer)
00211 {
00212 readAdvanced(buffer,address,1,0,clearBuffer);
00213 }
00214
00215
00216
00217 void OtsUDPFirmwareCore::OtsUDPFirmwareCore::readAdvanced(std::string& buffer,
00218 char* address,
00219 uint8_t size,
00220 uint8_t commandTypeOptions, bool clearBuffer)
00221 {
00222 if(size > 182)
00223 {
00224 __SS__ << "Invalid OtsUDPFirmwareCore::readAdvanced size: " << size << std::endl;
00225 __COUT_ERR__ << "\n" << ss.str();
00226 __SS_THROW__;
00227 }
00228
00229 if(buffer.size() + 2 + 8 > 2 + 8 + 8*182)
00230 {
00231 __SS__ << "Aborting. Buffer overflow attempt: " << buffer.size() << " + " <<
00232 2 + 8 << " > " << 2 + 8 + 8*182 << std::endl;
00233 __COUT_ERR__ << "\n" << ss.str();
00234 __SS_THROW__;
00235 }
00236
00237 if(clearBuffer)
00238 buffer.resize(0);
00239
00240 unsigned int begin = buffer.length();
00241 buffer.resize(buffer.length() + 2 + 8, '\0');
00242
00243 buffer[begin + 0] = (uint8_t)0 | commandTypeOptions;
00244 buffer[begin + 1] = size;
00245
00246
00247 std::copy_n(address,sizeof(uint64_t),&buffer[begin + 2]);
00248
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259 }
00260
00261
00262
00263 void OtsUDPFirmwareCore::OtsUDPFirmwareCore::readAdvanced(std::string& buffer,
00264 const uint64_t& address,
00265 uint8_t size,
00266 uint8_t commandTypeOptions, bool clearBuffer)
00267 {
00268 OtsUDPFirmwareCore::readAdvanced(buffer,(char *)&address,size,commandTypeOptions,clearBuffer);
00269 }
00270
00271
00272
00273 void OtsUDPFirmwareCore::setDataDestination(std::string& buffer,
00274 const std::string& ipAddress, const uint16_t port, bool clearBuffer)
00275 {
00276
00277
00278
00279 OtsUDPFirmwareCore::write(buffer,
00280 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_RESOLVE_MAC ,
00281 1 , clearBuffer);
00282
00283
00284
00285 uint64_t ip = 0;
00286 int ipArr[4];
00287 sscanf(ipAddress.c_str(),"%d.%d.%d.%d",
00288 &ipArr[3],
00289 &ipArr[2],
00290 &ipArr[1],
00291 &ipArr[0]
00292 );
00293 for(int i=0;i<4;++i)
00294 (((char *)&ip)[i]) += ipArr[i]&0x0FF;
00295
00296 writeDataDestinationIP(buffer,ip,false );
00297 writeDataDestinationPort(buffer,port,false);
00298
00299
00300
00301 }
00302
00303
00304 void OtsUDPFirmwareCore::setControlDestination(std::string& buffer,
00305 const std::string& ipAddress, const uint16_t port)
00306 {
00307
00308 OtsUDPFirmwareCore::writeAdvanced(buffer,
00309 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_RESOLVE_MAC ,
00310 1 );
00311
00312
00313 __COUT__ << "ipAddress = " << ipAddress << std::endl;
00314 uint64_t ip = 0;
00315 int ipArr[4];
00316 sscanf(ipAddress.c_str(),"%d.%d.%d.%d",
00317 &ipArr[3],
00318 &ipArr[2],
00319 &ipArr[1],
00320 &ipArr[0]
00321 );
00322 for(int i=0;i<4;++i)
00323 (((char *)&ip)[i]) += ipArr[i]&0x0FF;
00324
00325 writeControlDestinationIP(buffer,ip);
00326 writeControlDestinationPort(buffer,port);
00327 }
00328
00329
00330
00331 uint32_t OtsUDPFirmwareCore::createRegisterFromValue
00332 (std::string& readBuffer, std::string& receivedValue)
00333 {
00334 uint32_t retVal = *((uint32_t *)(&receivedValue[2]));
00335
00336
00337
00338
00339 return retVal;
00340 }
00341
00342
00343
00344 void OtsUDPFirmwareCore::writeDataDestinationIP(std::string& buffer, const uint64_t value,
00345 bool clearBuffer)
00346 {
00347 OtsUDPFirmwareCore::writeAdvanced(buffer,
00348 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_DEST_IP ,
00349 value ,
00350 0,clearBuffer);
00351 }
00352
00353
00354 void OtsUDPFirmwareCore::writeDataDestinationMAC(std::string& buffer, const uint64_t value,
00355 bool clearBuffer)
00356 {
00357 OtsUDPFirmwareCore::writeAdvanced(buffer,
00358 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_DEST_MAC ,
00359 value ,
00360 0,clearBuffer);
00361 }
00362
00363
00364 void OtsUDPFirmwareCore::writeDataDestinationPort(std::string& buffer, const uint64_t value,
00365 bool clearBuffer)
00366 {
00367 OtsUDPFirmwareCore::writeAdvanced(buffer,
00368 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_DEST_PORT ,
00369 value ,
00370 0,clearBuffer);
00371 }
00372
00373
00374 void OtsUDPFirmwareCore::readDataDestinationIP(std::string& buffer)
00375 {
00376 OtsUDPFirmwareCore::readAdvanced(buffer,
00377 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_DEST_IP );
00378 }
00379
00380
00381 void OtsUDPFirmwareCore::readDataDestinationMAC(std::string& buffer)
00382 {
00383 OtsUDPFirmwareCore::readAdvanced(buffer,
00384 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_DEST_MAC );
00385 }
00386
00387
00388 void OtsUDPFirmwareCore::readDataDestinationPort(std::string& buffer)
00389 {
00390 OtsUDPFirmwareCore::readAdvanced(buffer,
00391 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_DEST_PORT );
00392 }
00393
00394
00395 void OtsUDPFirmwareCore::writeControlDestinationIP(std::string& buffer, const uint64_t value)
00396 {
00397 OtsUDPFirmwareCore::writeAdvanced(buffer,
00398 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_DEST_IP ,
00399 value );
00400 }
00401
00402
00403 void OtsUDPFirmwareCore::writeControlDestinationMAC(std::string& buffer, const uint64_t value)
00404 {
00405 OtsUDPFirmwareCore::writeAdvanced(buffer,
00406 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_DEST_MAC ,
00407 value );
00408 }
00409
00410
00411 void OtsUDPFirmwareCore::writeControlDestinationPort(std::string& buffer, const uint64_t value)
00412 {
00413 OtsUDPFirmwareCore::writeAdvanced(buffer,
00414 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_DEST_PORT ,
00415 value );
00416 }
00417
00418
00419 void OtsUDPFirmwareCore::readControlDestinationIP(std::string& buffer)
00420 {
00421 OtsUDPFirmwareCore::readAdvanced(buffer,
00422 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_DEST_IP );
00423 }
00424
00425
00426 void OtsUDPFirmwareCore::readControlDestinationMAC(std::string& buffer)
00427 {
00428 OtsUDPFirmwareCore::readAdvanced(buffer,
00429 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_DEST_MAC );
00430 }
00431
00432
00433 void OtsUDPFirmwareCore::readControlDestinationPort(std::string& buffer)
00434 {
00435 OtsUDPFirmwareCore::readAdvanced(buffer,
00436 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_DEST_PORT );
00437 }
00438
00439
00440 void OtsUDPFirmwareCore::readUDPFirmwareVersion(std::string& buffer)
00441 {
00442 OtsUDPFirmwareCore::readAdvanced(buffer,
00443 UDP_CORE_BLOCK_ADDRESS | ADDR_SELF_VERSION );
00444 }
00445
00446
00447 void OtsUDPFirmwareCore::softEthernetReset(std::string& buffer)
00448 {
00449 OtsUDPFirmwareCore::writeAdvanced(buffer,
00450 UDP_CORE_BLOCK_ADDRESS | ADDR_SELF_RESET ,
00451 0x3 );
00452 }
00453
00454
00455 void OtsUDPFirmwareCore::hardEthernetReset(std::string& buffer)
00456 {
00457 OtsUDPFirmwareCore::writeAdvanced(buffer,
00458 UDP_CORE_BLOCK_ADDRESS | ADDR_SELF_RESET ,
00459 0x1 );
00460 }
00461
00462
00463 void OtsUDPFirmwareCore::clearEthernetReset(std::string& buffer)
00464 {
00465 OtsUDPFirmwareCore::writeAdvanced(buffer,
00466 UDP_CORE_BLOCK_ADDRESS | ADDR_SELF_RESET ,
00467 0 );
00468 }
00469
00470
00471 void OtsUDPFirmwareCore::startBurst(std::string& buffer)
00472 {
00473 __COUT__ << std::endl;
00474 OtsUDPFirmwareCore::writeAdvanced(buffer,
00475 UDP_CORE_BLOCK_ADDRESS | ADDR_BURST_MODE ,
00476 1 );
00477 }
00478
00479
00480 void OtsUDPFirmwareCore::stopBurst(std::string& buffer)
00481 {
00482 __COUT__ << std::endl;
00483 OtsUDPFirmwareCore::writeAdvanced(buffer,
00484 UDP_CORE_BLOCK_ADDRESS | ADDR_BURST_MODE ,
00485 0 );
00486 }
00487