ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
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
12namespace 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
Exception thrown when a logic error has occured.
Definition Exception.h:51
Exception thrown when a runtime error has occured.
Definition Exception.h:18
std::string to_string(const std::string &v)
RegisterInfo(uint32_t addressInBytes, uint32_t sizeInBytes)
void fetchFromRebotServer(uint32_t wordAddress, uint32_t numberOfWords, int32_t *dataLocation) const
virtual void write(uint32_t addressInBytes, int32_t const *data, size_t sizeInBytes) override
static void transferVectorToDataPtr(const std::vector< uint32_t > &source, int32_t *destination)
virtual void sendHeartbeat() override
virtual void read(uint32_t addressInBytes, int32_t *data, size_t sizeInBytes) override
boost::shared_ptr< Rebot::Connection > _tcpCommunicator
void sendRebotReadRequest(const uint32_t wordAddress, const uint32_t wordsToRead) const
RebotProtocol0(boost::shared_ptr< Rebot::Connection > &tcpCommunicator)