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 throw std::runtime_error(ss.str());
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 throw std::runtime_error(ss.str());
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 __SS__ << "\tAdded OtsUDPFirmwareCore::writeAdvanced to Buffer:-";
00138 for(uint32_t i=begin; i<buffer.size(); i++)
00139 {
00140 if(i==begin+2) ss << ":::";
00141 else if(i==begin+10) ss << ":::";
00142 ss << std::setfill('0') << std::setw(2) << std::hex << (((int16_t) buffer[i]) &0xFF) << "-" << std::dec;
00143 }
00144 ss << " added " << (buffer.size() - begin) << " to " << buffer.size();
00145 ss << std::endl;
00146 __COUT__ << "\n" << ss.str();
00147 }
00148
00149
00150
00151
00152 void OtsUDPFirmwareCore::OtsUDPFirmwareCore::writeAdvanced(std::string& buffer,
00153 const uint64_t& address,
00154 const char* data,
00155 uint8_t size,
00156 uint8_t commandTypeOptions,
00157 bool clearBuffer)
00158 {
00159 OtsUDPFirmwareCore::writeAdvanced(buffer,(char *)&address,data,size,commandTypeOptions,clearBuffer);
00160 }
00161
00162
00163 void OtsUDPFirmwareCore::OtsUDPFirmwareCore::writeAdvanced(std::string& buffer,
00164 const uint64_t& address,
00165 const uint64_t& data,
00166 uint8_t commandTypeOptions,
00167 bool clearBuffer)
00168 {
00169 OtsUDPFirmwareCore::writeAdvanced(buffer,(char *)&address,(char *)&data,1 ,commandTypeOptions,clearBuffer);
00170 }
00171
00172
00173 void OtsUDPFirmwareCore::OtsUDPFirmwareCore::writeAdvanced(std::string& buffer,
00174 const uint64_t& address,
00175 const std::vector<uint64_t>& data,
00176 uint8_t commandTypeOptions,
00177 bool clearBuffer)
00178 {
00179 OtsUDPFirmwareCore::writeAdvanced(buffer,(char *)&address,(char *)&data[0],data.size() ,commandTypeOptions,clearBuffer);
00180 }
00181
00182
00183 std::string OtsUDPFirmwareCore::read
00184 (char* address)
00185 {
00186 __COUT__ << "OTS pointer based read!! " << std::endl;
00187 std::string buffer;
00188 readAdvanced(buffer,address);
00189 return buffer;
00190 }
00191
00192
00193 void OtsUDPFirmwareCore::read
00194 (std::string& buffer, char* address, bool clearBuffer)
00195 {
00196 readAdvanced(buffer,address,1,0,clearBuffer);
00197 }
00198
00199
00200 void OtsUDPFirmwareCore::read
00201 (std::string& buffer, uint64_t address, bool clearBuffer)
00202 {
00203 readAdvanced(buffer,address,1,0,clearBuffer);
00204 }
00205
00206
00207 void OtsUDPFirmwareCore::read
00208 (std::string& buffer, uint32_t address, bool clearBuffer)
00209 {
00210 readAdvanced(buffer,address,1,0,clearBuffer);
00211 }
00212
00213
00214
00215 void OtsUDPFirmwareCore::OtsUDPFirmwareCore::readAdvanced(std::string& buffer,
00216 char* address,
00217 uint8_t size,
00218 uint8_t commandTypeOptions, bool clearBuffer)
00219 {
00220 if(size > 182)
00221 {
00222 __SS__ << "Invalid OtsUDPFirmwareCore::readAdvanced size: " << size << std::endl;
00223 __COUT_ERR__ << "\n" << ss.str();
00224 throw std::runtime_error(ss.str());
00225 }
00226
00227 if(buffer.size() + 2 + 8 > 2 + 8 + 8*182)
00228 {
00229 __SS__ << "Aborting. Buffer overflow attempt: " << buffer.size() << " + " <<
00230 2 + 8 << " > " << 2 + 8 + 8*182 << std::endl;
00231 __COUT_ERR__ << "\n" << ss.str();
00232 throw std::runtime_error(ss.str());
00233 }
00234
00235 if(clearBuffer)
00236 buffer.resize(0);
00237
00238 unsigned int begin = buffer.length();
00239 buffer.resize(buffer.length() + 2 + 8, '\0');
00240
00241 buffer[begin + 0] = (uint8_t)0 | commandTypeOptions;
00242 buffer[begin + 1] = size;
00243
00244
00245 std::copy_n(address,sizeof(uint64_t),&buffer[begin + 2]);
00246
00248 __SS__ << "\tAdded OtsUDPFirmwareCore::readAdvanced to Buffer:-";
00249 for(uint32_t i=begin; i<buffer.size(); i++)
00250 {
00251 if(i==begin+2) ss << ":::";
00252 else if(i==begin+10) ss << ":::";
00253 ss << std::setfill('0') << std::setw(2) << std::hex << (((int16_t) buffer[i]) &0xFF) << "-" << std::dec;
00254 }
00255 ss << std::endl;
00256 __COUT__ << "\n" << ss.str();
00257 }
00258
00259
00260
00261 void OtsUDPFirmwareCore::OtsUDPFirmwareCore::readAdvanced(std::string& buffer,
00262 const uint64_t& address,
00263 uint8_t size,
00264 uint8_t commandTypeOptions, bool clearBuffer)
00265 {
00266 OtsUDPFirmwareCore::readAdvanced(buffer,(char *)&address,size,commandTypeOptions,clearBuffer);
00267 }
00268
00269
00270
00271 void OtsUDPFirmwareCore::setDataDestination(std::string& buffer,
00272 const std::string& ipAddress, const uint16_t port, bool clearBuffer)
00273 {
00274
00275 __COUT__ << "dynamic mac address: " << std::hex <<
00276 uint64_t(UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_RESOLVE_MAC) << std::endl;
00277 OtsUDPFirmwareCore::write(buffer,
00278 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_RESOLVE_MAC ,
00279 1 , clearBuffer);
00280
00281
00282 __COUT__ << "ipAddress = " << ipAddress << std::endl;
00283 uint64_t ip = 0;
00284 int ipArr[4];
00285 sscanf(ipAddress.c_str(),"%d.%d.%d.%d",
00286 &ipArr[3],
00287 &ipArr[2],
00288 &ipArr[1],
00289 &ipArr[0]
00290 );
00291 for(int i=0;i<4;++i)
00292 (((char *)&ip)[i]) += ipArr[i]&0x0FF;
00293
00294 writeDataDestinationIP(buffer,ip,false );
00295 writeDataDestinationPort(buffer,port,false);
00296
00297
00298
00299 }
00300
00301
00302 void OtsUDPFirmwareCore::setControlDestination(std::string& buffer,
00303 const std::string& ipAddress, const uint16_t port)
00304 {
00305
00306 OtsUDPFirmwareCore::writeAdvanced(buffer,
00307 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_RESOLVE_MAC ,
00308 1 );
00309
00310
00311 __COUT__ << "ipAddress = " << ipAddress << std::endl;
00312 uint64_t ip = 0;
00313 int ipArr[4];
00314 sscanf(ipAddress.c_str(),"%d.%d.%d.%d",
00315 &ipArr[3],
00316 &ipArr[2],
00317 &ipArr[1],
00318 &ipArr[0]
00319 );
00320 for(int i=0;i<4;++i)
00321 (((char *)&ip)[i]) += ipArr[i]&0x0FF;
00322
00323 writeControlDestinationIP(buffer,ip);
00324 writeControlDestinationPort(buffer,port);
00325 }
00326
00327
00328
00329 uint32_t OtsUDPFirmwareCore::createRegisterFromValue
00330 (std::string& readBuffer, std::string& receivedValue)
00331 {
00332 uint32_t retVal = *((uint32_t *)(&receivedValue[2]));
00333
00334
00335
00336 __COUT__ << "Register value: 0x" << std::hex << retVal << std::dec << std::endl;
00337 return retVal;
00338 }
00339
00340
00341
00342 void OtsUDPFirmwareCore::writeDataDestinationIP(std::string& buffer, const uint64_t value,
00343 bool clearBuffer)
00344 {
00345 OtsUDPFirmwareCore::writeAdvanced(buffer,
00346 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_DEST_IP ,
00347 value ,
00348 0,clearBuffer);
00349 }
00350
00351
00352 void OtsUDPFirmwareCore::writeDataDestinationMAC(std::string& buffer, const uint64_t value,
00353 bool clearBuffer)
00354 {
00355 OtsUDPFirmwareCore::writeAdvanced(buffer,
00356 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_DEST_MAC ,
00357 value ,
00358 0,clearBuffer);
00359 }
00360
00361
00362 void OtsUDPFirmwareCore::writeDataDestinationPort(std::string& buffer, const uint64_t value,
00363 bool clearBuffer)
00364 {
00365 OtsUDPFirmwareCore::writeAdvanced(buffer,
00366 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_DEST_PORT ,
00367 value ,
00368 0,clearBuffer);
00369 }
00370
00371
00372 void OtsUDPFirmwareCore::readDataDestinationIP(std::string& buffer)
00373 {
00374 OtsUDPFirmwareCore::readAdvanced(buffer,
00375 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_DEST_IP );
00376 }
00377
00378
00379 void OtsUDPFirmwareCore::readDataDestinationMAC(std::string& buffer)
00380 {
00381 OtsUDPFirmwareCore::readAdvanced(buffer,
00382 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_DEST_MAC );
00383 }
00384
00385
00386 void OtsUDPFirmwareCore::readDataDestinationPort(std::string& buffer)
00387 {
00388 OtsUDPFirmwareCore::readAdvanced(buffer,
00389 UDP_CORE_BLOCK_ADDRESS | ADDR_DATA_DEST_PORT );
00390 }
00391
00392
00393 void OtsUDPFirmwareCore::writeControlDestinationIP(std::string& buffer, const uint64_t value)
00394 {
00395 OtsUDPFirmwareCore::writeAdvanced(buffer,
00396 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_DEST_IP ,
00397 value );
00398 }
00399
00400
00401 void OtsUDPFirmwareCore::writeControlDestinationMAC(std::string& buffer, const uint64_t value)
00402 {
00403 OtsUDPFirmwareCore::writeAdvanced(buffer,
00404 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_DEST_MAC ,
00405 value );
00406 }
00407
00408
00409 void OtsUDPFirmwareCore::writeControlDestinationPort(std::string& buffer, const uint64_t value)
00410 {
00411 OtsUDPFirmwareCore::writeAdvanced(buffer,
00412 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_DEST_PORT ,
00413 value );
00414 }
00415
00416
00417 void OtsUDPFirmwareCore::readControlDestinationIP(std::string& buffer)
00418 {
00419 OtsUDPFirmwareCore::readAdvanced(buffer,
00420 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_DEST_IP );
00421 }
00422
00423
00424 void OtsUDPFirmwareCore::readControlDestinationMAC(std::string& buffer)
00425 {
00426 OtsUDPFirmwareCore::readAdvanced(buffer,
00427 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_DEST_MAC );
00428 }
00429
00430
00431 void OtsUDPFirmwareCore::readControlDestinationPort(std::string& buffer)
00432 {
00433 OtsUDPFirmwareCore::readAdvanced(buffer,
00434 UDP_CORE_BLOCK_ADDRESS | ADDR_CTRL_DEST_PORT );
00435 }
00436
00437
00438 void OtsUDPFirmwareCore::readUDPFirmwareVersion(std::string& buffer)
00439 {
00440 OtsUDPFirmwareCore::readAdvanced(buffer,
00441 UDP_CORE_BLOCK_ADDRESS | ADDR_SELF_VERSION );
00442 }
00443
00444
00445 void OtsUDPFirmwareCore::ethernetReset(std::string& buffer)
00446 {
00447 OtsUDPFirmwareCore::writeAdvanced(buffer,
00448 UDP_CORE_BLOCK_ADDRESS | ADDR_SELF_RESET ,
00449 1 | (1<<1 ) );
00450 }
00451
00452 void OtsUDPFirmwareCore::ethernetUnreset(std::string& buffer)
00453 {
00454 OtsUDPFirmwareCore::writeAdvanced(buffer,
00455 UDP_CORE_BLOCK_ADDRESS | ADDR_SELF_RESET ,
00456 0 );
00457 }
00458
00459
00460 void OtsUDPFirmwareCore::startBurst(std::string& buffer)
00461 {
00462 __COUT__ << std::endl;
00463 OtsUDPFirmwareCore::writeAdvanced(buffer,
00464 UDP_CORE_BLOCK_ADDRESS | ADDR_BURST_MODE ,
00465 1 );
00466 }
00467
00468
00469 void OtsUDPFirmwareCore::stopBurst(std::string& buffer)
00470 {
00471 __COUT__ << std::endl;
00472 OtsUDPFirmwareCore::writeAdvanced(buffer,
00473 UDP_CORE_BLOCK_ADDRESS | ADDR_BURST_MODE ,
00474 0 );
00475 }
00476