Skip to content

Commit e1a125b

Browse files
authored
[swt] Extend SWT Read operations with an optional timeout
1 parent 42648eb commit e1a125b

File tree

6 files changed

+62
-29
lines changed

6 files changed

+62
-29
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,18 @@ The services are DIM RPC services. Every RPC is called with a string and expects
8080
* Parameters:
8181
* Sequence of SWT word and operation pairs as follows:
8282
* Operations may be:
83-
* SWT word with suffix `,write`
83+
* `write` with SWT prefix (e.g. `0x0000f00d,write`)
8484
* `reset` (without SWT word)
85-
* `read` (without SWT word)
85+
* `read` with optional TimeOut prefix (e.g. `2,read`)
8686
* Returns:
8787
* Sequence of SWT output as follows:
8888
* `write` always retuns `0`
8989
* `read` returns the SWT words present in the CRU SWT FIFO
9090
* `reset` returns nothing
9191

9292
* Example:
93-
* DIM input `reset\n0x0000000000badc0ffee,write\nread`
94-
* DIM output `0\n0x0000000000badc0ffee\n`
93+
* DIM input `reset\n0x0000000000badc0ffee,write\nread\n0xbadf00d,write\n4,read`
94+
* DIM output `0\n0x0000000000badc0ffee\n0x000000000000badf00d\n`
9595

9696
#### IC_SEQUENCE
9797

apps/ProgramAlfClient.cxx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,11 @@ class ProgramAlfClient : public AliceO2::Common::Program
111111
auto swtOut = swtSequence.write({ std::make_pair("0x0000000000000000000", "write"),
112112
std::make_pair("", "reset"),
113113
std::make_pair("0x000000001234", "write"),
114-
std::make_pair("", "read") });
114+
std::make_pair("", "read"),
115+
std::make_pair("0xdeadbeef", "write"),
116+
std::make_pair("1", "read"),
117+
std::make_pair("0xbadc0ffee", "write"),
118+
std::make_pair("4", "read") });
115119
getWarningLogger() << "swtSequence output: " << swtOut << endm;
116120

117121
auto scaOut = scaSequence.write({ std::make_pair("0x00010002", "0xff000000"),

src/AlfServer.cxx

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ std::string AlfServer::swtBlobWrite(const std::string& parameter, AlfLink link)
7070
{
7171

7272
std::vector<std::string> stringPairs = Util::split(parameter, argumentSeparator());
73-
std::vector<std::pair<SwtWord, Swt::Operation>> swtPairs = parseStringToSwtPairs(stringPairs);
73+
std::vector<std::pair<Swt::SwtData, Swt::Operation>> swtPairs = parseStringToSwtPairs(stringPairs);
7474
Swt swt = Swt(link);
7575
return swt.writeSequence(swtPairs);
7676
}
@@ -113,10 +113,10 @@ Sca::CommandData AlfServer::stringToScaPair(std::string stringPair)
113113
}
114114

115115
/// Converts a 76-bit hex number string
116-
std::pair<SwtWord, Swt::Operation> AlfServer::stringToSwtPair(const std::string stringPair)
116+
std::pair<Swt::SwtData, Swt::Operation> AlfServer::stringToSwtPair(const std::string stringPair)
117117
{
118118
std::vector<std::string> swtPair = Util::split(stringPair, pairSeparator());
119-
if (swtPair.size() != 1 && swtPair.size() != 2) {
119+
if (swtPair.size() < 1 || swtPair.size() > 2) {
120120
BOOST_THROW_EXCEPTION(
121121
AlfException() << ErrorInfo::Message("SWT word pair not formatted correctly"));
122122
}
@@ -125,10 +125,6 @@ std::pair<SwtWord, Swt::Operation> AlfServer::stringToSwtPair(const std::string
125125

126126
if (swtPair[swtPair.size() - 1] == "read") {
127127
operation = Swt::Operation::Read;
128-
if (swtPair.size() == 2) {
129-
BOOST_THROW_EXCEPTION(
130-
AlfException() << ErrorInfo::Message("Too many arguments for READ operation"));
131-
}
132128
} else if (swtPair[swtPair.size() - 1] == "write") {
133129
operation = Swt::Operation::Write;
134130
if (swtPair.size() == 1) {
@@ -145,8 +141,10 @@ std::pair<SwtWord, Swt::Operation> AlfServer::stringToSwtPair(const std::string
145141
BOOST_THROW_EXCEPTION(std::out_of_range("Parameter for SWT operation unkown"));
146142
}
147143

148-
SwtWord word;
144+
Swt::SwtData data;
145+
149146
if (operation == Swt::Operation::Write) {
147+
SwtWord word;
150148
std::string hexString = swtPair[0];
151149
std::string leadingHex = "0x";
152150

@@ -165,9 +163,17 @@ std::pair<SwtWord, Swt::Operation> AlfServer::stringToSwtPair(const std::string
165163
word.setHigh(std::stoul(ss.str().substr(0, 3), NULL, 16));
166164
word.setMed(std::stoul(ss.str().substr(3, 8), NULL, 16));
167165
word.setLow(std::stoul(ss.str().substr(11, 8), NULL, 16));
166+
167+
data = word;
168+
} else if (operation == Swt::Operation::Read && swtPair.size() == 2) {
169+
try {
170+
data = std::stoi(swtPair[0]);
171+
} catch (const std::exception& e) {
172+
BOOST_THROW_EXCEPTION(SwtException() << ErrorInfo::Message("SWT Read Timeout provided cannot be converted to int"));
173+
}
168174
}
169175

170-
return std::make_pair(word, operation);
176+
return std::make_pair(data, operation);
171177
}
172178

173179
std::pair<Ic::IcData, Ic::Operation> AlfServer::stringToIcPair(const std::string stringPair)
@@ -256,10 +262,10 @@ std::vector<Sca::CommandData> AlfServer::parseStringToScaCommands(std::vector<st
256262
return pairs;
257263
}
258264

259-
std::vector<std::pair<SwtWord, Swt::Operation>> AlfServer::parseStringToSwtPairs(std::vector<std::string> stringPairs)
265+
std::vector<std::pair<Swt::SwtData, Swt::Operation>> AlfServer::parseStringToSwtPairs(std::vector<std::string> stringPairs)
260266
{
261267

262-
std::vector<std::pair<SwtWord, Swt::Operation>> pairs;
268+
std::vector<std::pair<Swt::SwtData, Swt::Operation>> pairs;
263269
for (const auto& stringPair : stringPairs) {
264270
if (stringPair.find('#') == std::string::npos) {
265271
pairs.push_back(stringToSwtPair(stringPair));

src/AlfServer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,10 @@ class AlfServer
4949
static std::string icGbtI2cWrite(const std::string& parameter, AlfLink link);
5050

5151
static Sca::CommandData stringToScaPair(std::string stringPair);
52-
static std::pair<SwtWord, Swt::Operation> stringToSwtPair(const std::string stringPair);
52+
static std::pair<Swt::SwtData, Swt::Operation> stringToSwtPair(const std::string stringPair);
5353
static std::pair<Ic::IcData, Ic::Operation> stringToIcPair(const std::string stringPair);
5454
static std::vector<Sca::CommandData> parseStringToScaCommands(std::vector<std::string> stringPairs);
55-
static std::vector<std::pair<SwtWord, Swt::Operation>> parseStringToSwtPairs(std::vector<std::string> stringPairs);
55+
static std::vector<std::pair<Swt::SwtData, Swt::Operation>> parseStringToSwtPairs(std::vector<std::string> stringPairs);
5656
static std::vector<std::pair<Ic::IcData, Ic::Operation>> parseStringToIcPairs(std::vector<std::string> stringPairs);
5757

5858
/// serial -> link -> vector of RPC servers

src/Swt/Swt.cxx

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,12 @@ void Swt::reset()
5555
barWrite(sc_regs::SC_RESET.index, 0x0); //void cmd to sync clocks
5656
}
5757

58-
void Swt::read(std::vector<SwtWord>& words, SwtWord::Size wordSize)
58+
void Swt::read(std::vector<SwtWord>& words, TimeOut msTimeOut, SwtWord::Size wordSize)
5959
{
6060
uint32_t numWords = 0x0;
6161

62-
auto endTime = std::chrono::steady_clock::now() + std::chrono::milliseconds(10);
63-
while ((std::chrono::steady_clock::now() <= endTime) && (numWords < 1)) {
62+
auto timeOut = std::chrono::steady_clock::now() + std::chrono::milliseconds(msTimeOut);
63+
while ((std::chrono::steady_clock::now() < timeOut) && (numWords < 1)) {
6464
numWords = (barRead(sc_regs::SWT_MON.index) >> 16);
6565
}
6666

@@ -118,20 +118,32 @@ uint32_t Swt::barRead(uint32_t index)
118118
return read;
119119
}
120120

121-
std::string Swt::writeSequence(std::vector<std::pair<SwtWord, Operation>> words)
121+
std::string Swt::writeSequence(std::vector<std::pair<SwtData, Operation>> sequence)
122122
{
123123
std::stringstream resultBuffer;
124-
for (const auto& it : words) {
125-
SwtWord word = it.first;
124+
for (const auto& it : sequence) {
125+
SwtData data = it.first;
126126
try {
127127
if (it.second == Operation::Read) {
128128
std::vector<SwtWord> results;
129-
read(results);
129+
130+
int timeOut;
131+
try {
132+
timeOut = std::get<TimeOut>(data);
133+
} catch (...) { // no timeout was provided
134+
timeOut = -1;
135+
}
136+
if (timeOut >= 0) {
137+
read(results, timeOut);
138+
} else {
139+
read(results);
140+
}
141+
130142
for (const auto& result : results) {
131143
resultBuffer << result << "\n";
132144
}
133145
} else if (it.second == Operation::Write) {
134-
write(word);
146+
write(std::get<SwtWord>(data));
135147
resultBuffer << "0"
136148
<< "\n";
137149
} else if (it.second == Operation::Reset) {
@@ -142,7 +154,14 @@ std::string Swt::writeSequence(std::vector<std::pair<SwtWord, Operation>> words)
142154
} catch (const SwtException& e) {
143155
// If an SWT error occurs, we stop executing the sequence of commands and return the results as far as we got them, plus
144156
// the error message.
145-
std::string meaningfulMessage = (boost::format("SWT_SEQUENCE data=%s serial=%d link=%d, error='%s'") % word % mLink.serial % mLink.linkId % e.what()).str();
157+
std::string meaningfulMessage;
158+
if (it.second == Operation::Read) {
159+
meaningfulMessage = (boost::format("SWT_SEQUENCE READ timeout=%d serial=%d link=%d, error='%s'") % std::get<TimeOut>(data) % mLink.serial % mLink.linkId % e.what()).str();
160+
} else if (it.second == Operation::Write) {
161+
meaningfulMessage = (boost::format("SWT_SEQUENCE WRITE data=%s serial=%d link=%d, error='%s'") % std::get<SwtWord>(data) % mLink.serial % mLink.linkId % e.what()).str();
162+
} else {
163+
meaningfulMessage = (boost::format("SWT_SEQUENCE RESET serial=%d link=%d, error='%s'") % mLink.serial % mLink.linkId % e.what()).str();
164+
}
146165
getErrorLogger() << meaningfulMessage << endm;
147166
resultBuffer << meaningfulMessage;
148167
BOOST_THROW_EXCEPTION(SwtException() << ErrorInfo::Message(resultBuffer.str()));

src/Swt/Swt.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#define ALICEO2_ALF_SRC_SWT_SWT_H
2828

2929
#include <string>
30+
#include <variant>
3031

3132
#include "Common.h"
3233
#include "ReadoutCard/RegisterReadWriteInterface.h"
@@ -45,15 +46,18 @@ class Swt
4546
public:
4647
Swt(AlfLink link);
4748

49+
typedef int TimeOut;
50+
typedef std::variant<SwtWord, TimeOut> SwtData;
51+
4852
void reset();
4953
uint32_t write(const SwtWord& swtWord);
50-
void read(std::vector<SwtWord>& words, SwtWord::Size wordSize = SwtWord::Size::High);
54+
void read(std::vector<SwtWord>& word, TimeOut msTimeOut = 10, SwtWord::Size wordSize = SwtWord::Size::High);
5155

5256
enum Operation { Read,
5357
Write,
5458
Reset };
5559

56-
std::string writeSequence(std::vector<std::pair<SwtWord, Operation>> words);
60+
std::string writeSequence(std::vector<std::pair<SwtData, Operation>> sequence);
5761

5862
private:
5963
void setChannel(int gbtChannel);

0 commit comments

Comments
 (0)