ChimeraTK-DeviceAccess  03.18.00
RebotProtocol0.cc
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2 // SPDX-License-Identifier: LGPL-3.0-or-later
3 
4 #include "RebotProtocol0.h"
5 
6 #include "Connection.h"
7 #include "Exception.h"
9 
10 #include <iostream>
11 
12 namespace ChimeraTK {
13  using namespace Rebot;
14 
15  RebotProtocol0::RebotProtocol0(boost::shared_ptr<Connection>& tcpCommunicator) : _tcpCommunicator(tcpCommunicator) {}
16 
17  RebotProtocol0::RegisterInfo::RegisterInfo(uint32_t addressInBytes, uint32_t sizeInBytes) {
18  if(sizeInBytes % 4 != 0) {
19  throw ChimeraTK::logic_error("\"size\" argument must be a multiplicity of 4");
20  }
21  // address == byte address; This should be converted into word address
22  if(addressInBytes % 4 != 0) {
23  throw ChimeraTK::logic_error("Register address is not valid");
24  }
25 
26  addressInWords = addressInBytes / 4;
27  nWords = sizeInBytes / 4;
28  }
29 
30  void RebotProtocol0::read(uint32_t addressInBytes, int32_t* data, size_t sizeInBytes) {
31  // locking is happening in the backend
32  // check for isOpen() is happening in the backend which does the bookkeeping
33 
34  RegisterInfo registerInfo(addressInBytes, sizeInBytes);
35 
36  // read implementation for protocol 0 : we are limited in the read size and
37  // have to do multiple calls to fetchFromRebotServer
38 
39  size_t iterationsRequired = registerInfo.nWords / READ_BLOCK_SIZE;
40  size_t leftOverWords = registerInfo.nWords % READ_BLOCK_SIZE;
41 
42  // read in till the last multiple of READ_BLOCK_SIZE
43  for(size_t count = 0; count < iterationsRequired; ++count) {
45  registerInfo.addressInWords + (count * READ_BLOCK_SIZE), READ_BLOCK_SIZE, data + (count * READ_BLOCK_SIZE));
46  }
47  // read remaining from the last multiple of READ_BLOCK_SIZE
48  fetchFromRebotServer(registerInfo.addressInWords + (iterationsRequired * READ_BLOCK_SIZE), leftOverWords,
49  data + (iterationsRequired * READ_BLOCK_SIZE));
50  }
51 
52  void RebotProtocol0::write(uint32_t addressInBytes, int32_t const* data, size_t sizeInBytes) {
53  RegisterInfo registerInfo(addressInBytes, sizeInBytes);
54 
55  // Implementation for protocol version 0: Only single word write possible
56  std::vector<uint32_t> packet(3);
57  for(unsigned int i = 0; i < registerInfo.nWords; ++i) {
58  packet[0] = SINGLE_WORD_WRITE;
59  packet[1] = registerInfo.addressInWords++;
60  packet[2] = static_cast<uint32_t>(data[i]);
61  _tcpCommunicator->write(packet);
62  _tcpCommunicator->read(1); // response is ignored for now
63  }
64  }
65 
66  void RebotProtocol0::fetchFromRebotServer(uint32_t wordAddress, uint32_t numberOfWords, int32_t* dataLocation) const {
67  sendRebotReadRequest(wordAddress, numberOfWords);
68 
69  // first check that the response starts with READ_ACK. If it is an error code
70  // there might be just one word in the response.
71  std::vector<uint32_t> responseCode = _tcpCommunicator->read(1);
72  if(responseCode[0] != Rebot::READ_ACK) {
73  // FIXME: can we do somwthing more clever here?
74  throw ChimeraTK::runtime_error("Reading via ReboT failed. Response code: " + std::to_string(responseCode[0]));
75  }
76 
77  // now that we know that the command worked on the server side we can read the
78  // rest of the data
79  std::vector<uint32_t> readData = _tcpCommunicator->read(numberOfWords);
80  transferVectorToDataPtr(readData, dataLocation);
81  }
82 
83  void RebotProtocol0::sendRebotReadRequest(const uint32_t wordAddress, const uint32_t wordsToRead) const {
84  unsigned int datasendSize = 3 * sizeof(int);
85  std::vector<char> datasend(datasendSize);
86  std::vector<uint32_t> packet(3);
87  packet[0] = MULTI_WORD_READ;
88  packet[1] = wordAddress;
89  packet[2] = wordsToRead;
90  _tcpCommunicator->write(packet);
91  }
92 
93  void RebotProtocol0::transferVectorToDataPtr(const std::vector<uint32_t>& source, int32_t* destination) {
94  // FIXME: just use memcopy
95  for(const auto& i : source) {
96  *destination = static_cast<int32_t>(i);
97  ++destination; // this will not change the destination ptr value outside the
98  // scope of this function (signature pass by value)
99  }
100  }
101 
103  // just do nothing in v0
104  }
105 
106 } // namespace ChimeraTK
ChimeraTK::RebotProtocol0::_tcpCommunicator
boost::shared_ptr< Rebot::Connection > _tcpCommunicator
Definition: RebotProtocol0.h:33
ChimeraTK::RebotProtocol0::sendHeartbeat
virtual void sendHeartbeat() override
Definition: RebotProtocol0.cc:102
ChimeraTK::runtime_error
Exception thrown when a runtime error has occured.
Definition: Exception.h:18
RebotProtocol0.h
ChimeraTK::RebotProtocol0::write
virtual void write(uint32_t addressInBytes, int32_t const *data, size_t sizeInBytes) override
Definition: RebotProtocol0.cc:52
ChimeraTK::RebotProtocol0::transferVectorToDataPtr
static void transferVectorToDataPtr(const std::vector< uint32_t > &source, int32_t *destination)
Definition: RebotProtocol0.cc:93
ChimeraTK::RebotProtocol0::RebotProtocol0
RebotProtocol0(boost::shared_ptr< Rebot::Connection > &tcpCommunicator)
Definition: RebotProtocol0.cc:15
ChimeraTK::RebotProtocol0::RegisterInfo
Definition: RebotProtocol0.h:24
ChimeraTK::RebotProtocol0::RegisterInfo::RegisterInfo
RegisterInfo(uint32_t addressInBytes, uint32_t sizeInBytes)
Definition: RebotProtocol0.cc:17
ChimeraTK::RebotProtocol0::sendRebotReadRequest
void sendRebotReadRequest(const uint32_t wordAddress, const uint32_t wordsToRead) const
Definition: RebotProtocol0.cc:83
Connection.h
ChimeraTK::RebotProtocol0::fetchFromRebotServer
void fetchFromRebotServer(uint32_t wordAddress, uint32_t numberOfWords, int32_t *dataLocation) const
Definition: RebotProtocol0.cc:66
ChimeraTK::RebotProtocol0::RegisterInfo::nWords
uint32_t nWords
Definition: RebotProtocol0.h:26
ChimeraTK::RebotProtocol0::RegisterInfo::addressInWords
uint32_t addressInWords
Definition: RebotProtocol0.h:25
Exception.h
ChimeraTK
Definition: DummyBackend.h:16
ChimeraTK::to_string
std::string to_string(Boolean &value)
Definition: SupportedUserTypes.h:59
ChimeraTK::RebotProtocol0::read
virtual void read(uint32_t addressInBytes, int32_t *data, size_t sizeInBytes) override
Definition: RebotProtocol0.cc:30
ChimeraTK::logic_error
Exception thrown when a logic error has occured.
Definition: Exception.h:51
RebotProtocolDefinitions.h