00001 #include "otsdaq-components/DAQHardware/PurdueFirmwareCore.h"
00002 #include "otsdaq-core/BitManipulator/BitManipulator.h"
00003 #include "otsdaq-components/DAQHardware/FirmwareBaseDefinitions.h"
00004 #include "otsdaq-core/MessageFacility/MessageFacility.h"
00005 #include "otsdaq-core/Macros/CoutMacros.h"
00006 #include <sys/socket.h>
00007 #include <netinet/in.h>
00008 #include <arpa/inet.h>
00009 #include <iostream>
00010 #include <cstdlib>
00011
00012 using namespace ots;
00013
00014
00015 PurdueFirmwareCore::PurdueFirmwareCore(unsigned int version):
00016 FrontEndFirmwareBase(version)
00017 {
00018 }
00019
00020
00021 PurdueFirmwareCore::~PurdueFirmwareCore(void)
00022 {}
00023
00024
00025 void PurdueFirmwareCore::init(void)
00026 {}
00027
00028
00029 void PurdueFirmwareCore::setDataDestination(std::string& buffer,
00030 const std::string& ipAddress, const uint16_t port,bool clearBuffer)
00031 {
00032
00033
00034 if(clearBuffer)
00035 buffer.resize(0);
00036 }
00037
00038
00039 std::string PurdueFirmwareCore::read(char* address)
00040 {
00041 std::string buffer;
00042 read(buffer, *(uint32_t*)address);
00043 return buffer;
00044 }
00045
00046
00047 std::string PurdueFirmwareCore::write(char* address, char* data)
00048 {
00049 std::string buffer;
00050 write(buffer, *(uint32_t*)address, *(uint32_t*)data);
00051 return buffer;
00052 }
00053
00054
00055 void PurdueFirmwareCore::write(std::string& buffer, uint32_t address, uint32_t data,bool clearBuffer)
00056 {
00057 if(clearBuffer)
00058 buffer.resize(0);
00059
00060
00061 unsigned int begin = buffer.length();
00062 unsigned int numberOfBufferedCommands = getNumberOfBufferedCommands(buffer);
00063 buffer.resize(buffer.length() + 12, '\0');
00064 if (begin != 0)
00065 begin -= 1;
00066 buffer[begin + 0] = numberOfBufferedCommands + 1;
00067 buffer[begin + 1] = WRITE;
00068 buffer[begin + 2] = 0;
00069 buffer[begin + 3] = 8;
00070 buffer[begin + 4] = (address >> 24) & 0xff;
00071 buffer[begin + 5] = (address >> 16) & 0xff;
00072 buffer[begin + 6] = (address >> 8) & 0xff;
00073 buffer[begin + 7] = address & 0xff;
00074 buffer[begin + 8] = (data >> 24) & 0xff;
00075 buffer[begin + 9] = (data >> 16) & 0xff;
00076 buffer[begin + 10] = (data >> 8) & 0xff;
00077 buffer[begin + 11] = data & 0xff;
00078 if (begin == 0)
00079 buffer += '\0';
00080
00081 }
00082
00083
00084 void PurdueFirmwareCore::waitSet(std::string& buffer, uint32_t address, uint32_t data, uint32_t timeout,bool clearBuffer)
00085 {
00086 if(clearBuffer)
00087 buffer.resize(0);
00088
00089 unsigned int begin = buffer.length();
00090 unsigned int numberOfBufferedCommands = getNumberOfBufferedCommands(buffer);
00091 buffer.resize(buffer.length() + 16, '\0');
00092 if (begin != 0)
00093 begin -= 1;
00094 buffer[begin + 0] = numberOfBufferedCommands + 1;
00095 buffer[begin + 1] = WAITSET;
00096 buffer[begin + 2] = 0;
00097 buffer[begin + 3] = 12;
00098 buffer[begin + 4] = (address >> 24) & 0xff;
00099 buffer[begin + 5] = (address >> 16) & 0xff;
00100 buffer[begin + 6] = (address >> 8) & 0xff;
00101 buffer[begin + 7] = address & 0xff;
00102 buffer[begin + 8] = (data >> 24) & 0xff;
00103 buffer[begin + 9] = (data >> 16) & 0xff;
00104 buffer[begin + 10] = (data >> 8) & 0xff;
00105 buffer[begin + 11] = data & 0xff;
00106 buffer[begin + 12] = (timeout >> 24) & 0xff;
00107 buffer[begin + 13] = (timeout >> 16) & 0xff;
00108 buffer[begin + 14] = (timeout >> 8) & 0xff;
00109 buffer[begin + 15] = timeout & 0xff;
00110 if (begin == 0)
00111 buffer += '\0';
00112
00113 }
00114
00115
00116 void PurdueFirmwareCore::waitClear(std::string& buffer, uint32_t address, uint32_t data, uint32_t timeout,bool clearBuffer)
00117 {
00118 if(clearBuffer)
00119 buffer.resize(0);
00120
00121 unsigned int begin = buffer.length();
00122 unsigned int numberOfBufferedCommands = getNumberOfBufferedCommands(buffer);
00123 buffer.resize(buffer.length() + 16, '\0');
00124 if (begin != 0)
00125 begin -= 1;
00126 buffer[begin + 0] = numberOfBufferedCommands + 1;
00127 buffer[begin + 1] = WAITCLR;
00128 buffer[begin + 2] = 0;
00129 buffer[begin + 3] = 12;
00130 buffer[begin + 4] = (address >> 24) & 0xff;
00131 buffer[begin + 5] = (address >> 16) & 0xff;
00132 buffer[begin + 6] = (address >> 8) & 0xff;
00133 buffer[begin + 7] = address & 0xff;
00134 buffer[begin + 8] = (data >> 24) & 0xff;
00135 buffer[begin + 9] = (data >> 16) & 0xff;
00136 buffer[begin + 10] = (data >> 8) & 0xff;
00137 buffer[begin + 11] = data & 0xff;
00138 buffer[begin + 12] = (timeout >> 24) & 0xff;
00139 buffer[begin + 13] = (timeout >> 16) & 0xff;
00140 buffer[begin + 14] = (timeout >> 8) & 0xff;
00141 buffer[begin + 15] = timeout & 0xff;
00142 if (begin == 0)
00143 buffer += '\0';
00144
00145 }
00146
00147
00148 void PurdueFirmwareCore::read(std::string& buffer, uint32_t address,bool clearBuffer)
00149 {
00150 if(clearBuffer)
00151 buffer.resize(0);
00152
00153 unsigned int begin = buffer.length();
00154 unsigned int numberOfBufferedCommands = getNumberOfBufferedCommands(buffer);
00155 buffer.resize(buffer.length() + 8, '\0');
00156 if (begin != 0)
00157 begin -= 1;
00158 buffer[begin + 0] = numberOfBufferedCommands + 1;
00159 buffer[begin + 1] = READ;
00160 buffer[begin + 2] = 0;
00161 buffer[begin + 3] = 4;
00162 buffer[begin + 4] = (address >> 24) & 0xff;
00163 buffer[begin + 5] = (address >> 16) & 0xff;
00164 buffer[begin + 6] = (address >> 8) & 0xff;
00165 buffer[begin + 7] = address & 0xff;
00166 if (begin == 0)
00167 buffer += '\0';
00168
00169 }
00170
00171
00172 unsigned int PurdueFirmwareCore::getNumberOfBufferedCommands(std::string& buffer)
00173 {
00174 if (buffer.length() == 0)
00175 return 0;
00176 unsigned int bufferPosition = 0;
00177 unsigned int commandNumber = 0;
00178 while (bufferPosition < buffer.length() - 1)
00179 {
00180 bufferPosition += (unsigned int) buffer[bufferPosition + 3] + 4;
00181 ++commandNumber;
00182 }
00183 return commandNumber;
00184 }
00185
00186
00187 std::string PurdueFirmwareCore::compareSendAndReceive(const std::string& sentBuffer, std::string& acknowledgment)
00188 {
00189 std::string reSendBuffer;
00190 unsigned int skipBuffer = 0;
00191 unsigned int skipAcknow = 0;
00192 unsigned int remainBufferCommands;
00193 unsigned int remainAcknowCommands;
00194
00195 std::cout << __COUT_HDR_FL__ << "Comparing sent buffer and received acknowledgment!!!" << std::endl;
00196
00197 std::cout << __COUT_HDR_FL__ << "Buffer size (send): " << sentBuffer.size() << std::endl;
00198 std::cout << __COUT_HDR_FL__ << "Acknowledgment size (receive): " << acknowledgment.size() << std::endl;
00199
00200 while(skipBuffer < sentBuffer.size())
00201 {
00202
00203 for (int position = 0; position < 4; position++)
00204 {
00205 if (position + skipBuffer >= sentBuffer.size())
00206 {
00207 reSendBuffer.clear();
00208 std::cout << __COUT_HDR_FL__ << "Done... Works!!!" << std::endl;
00209 return reSendBuffer;
00210 }
00211
00212 if (position == 0)
00213 {
00214 if (sentBuffer[position + skipBuffer] != acknowledgment[position + skipAcknow])
00215 {
00216 std::cout << __COUT_HDR_FL__ << "ERROR - Sent " << position + skipBuffer << "th: " << std::hex << (unsigned int)sentBuffer[position + skipBuffer] << std::dec
00217 << " different from Received " << position + skipAcknow << "th:"
00218 << std::hex << (unsigned int)acknowledgment[position + skipAcknow] << std::dec;
00219 std::cout << __COUT_HDR_FL__ << "Position: " << position << std::endl;
00220 reSendBuffer.clear();
00221 for (unsigned int i = skipBuffer; i < (skipBuffer + 4 + sentBuffer[skipBuffer + 3]); i++)
00222 {
00223 reSendBuffer+= sentBuffer[i];
00224 }
00225 return reSendBuffer;
00226 }
00227 }
00228
00229 if (position == 1)
00230 {
00231 if ( (sentBuffer[position + skipBuffer]) != (acknowledgment[position + skipAcknow] & 0xf) )
00232 {
00233 std::cout << __COUT_HDR_FL__ << "ERROR - Sent " << position + skipBuffer << "th: " << std::hex << (unsigned int)sentBuffer[position + skipBuffer] << std::dec
00234 << " different from Received " << position + skipAcknow << "th:"
00235 << std::hex << (unsigned int)acknowledgment[position + skipAcknow] << std::dec;
00236 std::cout << __COUT_HDR_FL__ << "Position: " << position << std::endl;
00237 reSendBuffer.clear();
00238 for (unsigned int i = skipBuffer; i < (skipBuffer + 4 + sentBuffer[skipBuffer + 3]); i++)
00239 {
00240 reSendBuffer+= sentBuffer[i];
00241 }
00242 return reSendBuffer;
00243 }
00244 }
00245
00246 if (position == 2)
00247 {
00248 if ( (sentBuffer[position + skipBuffer] != 0) || (acknowledgment[position + skipAcknow] != 0) )
00249 {
00250 std::cout << __COUT_HDR_FL__ << "ERROR - Sent " << position + skipBuffer << "th: " << std::hex << (unsigned int)sentBuffer[position + skipBuffer] << std::dec
00251 << " different from Received " << position + skipAcknow << "th:"
00252 << std::hex << (unsigned int)acknowledgment[position + skipAcknow] << std::dec << std::endl;
00253 std::cout << __COUT_HDR_FL__ << "Position: " << position << std::endl;
00254 reSendBuffer.clear();
00255 for (unsigned int i = skipBuffer; i < (skipBuffer + 4 + sentBuffer[skipBuffer + 3]); i++)
00256 {
00257 reSendBuffer+= sentBuffer[i];
00258 }
00259 return reSendBuffer;
00260 }
00261 }
00262
00263 if ( position == 3)
00264 {
00265 remainBufferCommands = sentBuffer[position + skipBuffer];
00266 remainAcknowCommands = acknowledgment[position + skipAcknow];
00267
00268 if ( ((remainBufferCommands == 12) && (remainAcknowCommands == 4)) || ((remainBufferCommands == 8) && (remainAcknowCommands == 0)) )
00269 {
00270 skipBuffer += (4 + remainBufferCommands);
00271 skipAcknow += (4 + remainAcknowCommands);
00272 }
00273 else
00274 {
00275 std::cout << __COUT_HDR_FL__ << "ERROR - Sent " << position + skipBuffer << "th: " << std::hex << (unsigned int)sentBuffer[position + skipBuffer] << std::dec
00276 << " not compatible with Received " << position + skipAcknow << "th:"
00277 << std::hex << (unsigned int)acknowledgment[position + skipAcknow] << std::dec << std::endl;
00278 std::cout << __COUT_HDR_FL__ << "Position: " << position << std::endl;
00279 reSendBuffer.clear();
00280 for (unsigned int i = skipBuffer; i < (skipBuffer + 4 + sentBuffer[skipBuffer + 3]); i++)
00281 {
00282 reSendBuffer+= sentBuffer[i];
00283 }
00284 return reSendBuffer;
00285 }
00286 }
00287 }
00288 }
00289
00290 reSendBuffer.clear();
00291 std::cout << __COUT_HDR_FL__ << "Done... Works!!!" << std::endl;
00292 return reSendBuffer;
00293 }
00294
00295
00296 uint32_t PurdueFirmwareCore::createRegisterFromValue(std::string& readBuffer, std::string& receivedValue)
00297 {
00298 for (int position = 0; position < 8; position++)
00299 {
00300 if (position == 0 || position == 4 || position == 5 || position == 6 || position == 7)
00301 {
00302 if (readBuffer[position] != receivedValue[position])
00303 {
00304 std::cout << __COUT_HDR_FL__
00305 << "ERROR - SentBuffer position " << position << " value: " << std::hex << (unsigned int)readBuffer[position] << std::dec
00306 << " different from ReceivedBuffer position " << position << " value: " << std::hex << (unsigned int)receivedValue[position] << std::dec
00307 << std::endl;
00308 return 0;
00309 }
00310 }
00311
00312 if (position == 1)
00313 {
00314 if ( (readBuffer[position] != (receivedValue[position] & 0xf)) )
00315 {
00316 std::cout << __COUT_HDR_FL__
00317 << "ERROR - SentBuffer position " << position << " value: " << std::hex << (unsigned int)readBuffer[position] << std::dec
00318 << " different from ReceivedBuffer position " << position << " value: " << std::hex << (unsigned int)receivedValue[position] << std::dec
00319 << std::endl;
00320 return 0;
00321 }
00322 }
00323
00324 if (position == 2)
00325 {
00326 if ( (readBuffer[position] != 0) || (receivedValue[position] != 0) )
00327 {
00328 std::cout << __COUT_HDR_FL__
00329 << "ERROR - SentBuffer position " << position << " value: " << std::hex << (unsigned int)readBuffer[position] << std::dec
00330 << " different from ReceivedBuffer position " << position << " value: " << std::hex << (unsigned int)receivedValue[position] << std::dec
00331 << std::endl;
00332 return 0;
00333 }
00334 }
00335
00336 if ( position == 3)
00337 {
00338 if ( (readBuffer[position] != 4) || (receivedValue[position] != 8) )
00339 {
00340 std::cout << __COUT_HDR_FL__
00341 << "ERROR - SentBuffer position " << position << " value: " << std::hex << (unsigned int)readBuffer[position] << std::dec
00342 << " different from ReceivedBuffer position " << position << " value: " << std::hex << (unsigned int)receivedValue[position] << std::dec
00343 << std::endl;
00344 return 0;
00345 }
00346 }
00347 }
00348
00349 uint32_t registerValue;
00350
00351 registerValue = ((unsigned int)receivedValue[8] << 24)
00352 + ((unsigned int)receivedValue[9] << 16)
00353 + ((unsigned int)receivedValue[10] << 8)
00354 + (unsigned int)receivedValue[11];
00355
00356 std::cout << __COUT_HDR_FL__ << "No problem encountered! Register value created!!! " << std::endl;
00357
00358 return registerValue;
00359 }
00360