Skip to content

Commit 6b483e8

Browse files
committed
added SWT functions: read_multiple and set_read_timeout
1 parent 23f542e commit 6b483e8

File tree

4 files changed

+145
-42
lines changed

4 files changed

+145
-42
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,19 +126,26 @@ It extends the `SCA_SEQUENCE` to add the following functionality:
126126
* `read` with optional TimeOut prefix (e.g. `2,read`)
127127
* `wait` with optional WaitTime prefix in ms (e.g. `5,wait`), defaults to 3
128128
* `lock` which instructs ALF to execute the sequence atomically (needs to lead the sequence)
129+
* `read_multiple` with count prefix (e.g. `2,read_multiple`): read a number of words
130+
* `set_read_timeout` to define default read TimeOut in milliseconds (for read and read_multiple operations). (e.g. `10,set_read_timeout`). Timeout argument is optional, in which case the default value is reset.
131+
129132
* Returns:
130133
* Sequence of SWT output as follows:
131134
* `write` always retuns `0`
132135
* `read` returns the SWT words present in the CRU SWT FIFO
133136
* `sc_reset` returns nothing
134137
* `wait` returns time waited
135138
* `lock` returns nothing
136-
139+
* `read_multiple` returns the SWT words present in the CRU SWT FIFO (for the number of read requested)
140+
* `set_read_timeout` returns the new timeout
141+
137142
* Example:
138143
* DIM input `sc_reset\n0x0000000000badc0ffee,write\nread\n0xbadf00d,write\n4,read`
139144
* DIM input (atomic) `lock\nsc_reset\n0x0000000000badc0ffee,write\nread\n0xbadf00d,write\n4,read`
140145
* DIM output `0\n0x0000000000badc0ffee\n0\n0x000000000000badf00d\n`
141146

147+
NB: when calling the service from DIM did client for testing, use double quotes around the full query string.
148+
142149
##### IC_SEQUENCE
143150

144151
* Parameters:

include/Alf/Swt.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ class Swt : public ScBase
5959

6060
/// Enum for the different SWT operation types
6161
enum Operation { Read,
62+
ReadMultiple,
63+
SetReadTimeout,
6264
Write,
6365
SCReset,
6466
Wait,
@@ -90,6 +92,14 @@ class Swt : public ScBase
9092
/// \throws o2::alf::SwtException in case of no SWT words in FIFO, or timeout exceeded
9193
std::vector<SwtWord> read(SwtWord::Size wordSize = SwtWord::Size::Low, TimeOut msTimeOut = DEFAULT_SWT_TIMEOUT_MS);
9294

95+
/// Reads multiple SWT words
96+
/// \param wordSize The size of the SWT words to be read
97+
/// \param numberOfWords The number of SWT words to be read
98+
/// \param msTimeOut Timeout of the read operation in ms
99+
/// \return A vector of SWT words read
100+
/// \throws o2::alf::SwtException in case of no SWT words in FIFO, or timeout exceeded
101+
std::vector<SwtWord> readMultiple(SwtWord::Size wordSize = SwtWord::Size::Low, unsigned int numberOfWords = 1, TimeOut msTimeOut = DEFAULT_SWT_TIMEOUT_MS);
102+
93103
/// Executes an SWT sequence
94104
/// \param sequence A vector of Operation and Data pairs
95105
/// \param lock Boolean enabling implicit locking
@@ -115,10 +125,11 @@ class Swt : public ScBase
115125
static Operation StringToSwtOperation(std::string op);
116126

117127
static constexpr int DEFAULT_SWT_TIMEOUT_MS = 10;
128+
static constexpr int DEFAULT_SWT_WAIT_TIME_MS = 3;
118129

119130
private:
120-
static constexpr int DEFAULT_SWT_WAIT_TIME_MS = 3;
121131
SwtWord::Size mSwtWordSize = SwtWord::Size::Low;
132+
TimeOut readTimeout = DEFAULT_SWT_TIMEOUT_MS;
122133
};
123134

124135
} // namespace alf

src/AlfServer.cxx

Lines changed: 52 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -326,37 +326,65 @@ std::pair<Swt::Operation, Swt::Data> AlfServer::stringToSwtPair(const std::strin
326326
Swt::Operation operation;
327327
Swt::Data data;
328328

329-
if (swtPair[swtPair.size() - 1] == "lock") {
330-
operation = Swt::Operation::Lock;
329+
bool getIntParam = false;
330+
int numberOfMandatoryParams = -1; // do not care about number of parameters
331+
332+
try {
333+
operation = Swt::StringToSwtOperation(swtPair[swtPair.size() - 1]);
334+
} catch(...) {
335+
BOOST_THROW_EXCEPTION(std::out_of_range("SWT unkown operation " + swtPair[swtPair.size() - 1]));
336+
}
337+
338+
switch(operation) {
339+
case Swt::Operation::Lock:
340+
data = 0;
341+
getIntParam = true;
342+
break;
343+
case Swt::Operation::SetReadTimeout:
344+
data = Swt::DEFAULT_SWT_TIMEOUT_MS;
345+
getIntParam = true;
346+
break;
347+
case Swt::Operation::Read:
348+
getIntParam = true;
349+
break;
350+
case Swt::Operation::ReadMultiple:
351+
getIntParam = true;
352+
numberOfMandatoryParams = 1;
353+
break;
354+
case Swt::Operation::Write:
355+
numberOfMandatoryParams = 1;
356+
break;
357+
case Swt::Operation::SCReset:
358+
numberOfMandatoryParams = 0;
359+
break;
360+
case Swt::Operation::Wait:
361+
data = Swt::DEFAULT_SWT_WAIT_TIME_MS;
362+
getIntParam = true;
363+
break;
364+
default:
365+
BOOST_THROW_EXCEPTION(std::out_of_range("Parameter for SWT operation unkown"));
366+
}
367+
368+
// check number of mandatory parameters, if set
369+
if (numberOfMandatoryParams >= 0) {
370+
if (((int)swtPair.size() - 1) != numberOfMandatoryParams) {
371+
BOOST_THROW_EXCEPTION(
372+
AlfException() << ErrorInfo::Message("SWT wrong number of arguments for " + Swt::SwtOperationToString(operation) + " operation"));
373+
}
374+
}
375+
376+
// get int parameter if needed, and available
377+
if (getIntParam) {
331378
if (swtPair.size() == 2) {
332379
try {
333380
data = std::stoi(swtPair[0]);
334381
} catch (const std::exception& e) {
335-
BOOST_THROW_EXCEPTION(SwtException() << ErrorInfo::Message("SWT lock WaitTime provided cannot be converted to int"));
382+
BOOST_THROW_EXCEPTION(SwtException() << ErrorInfo::Message("SWT " + Swt::SwtOperationToString(operation) + " argument provided cannot be converted to int"));
336383
}
337-
} else {
338-
data = 0;
339384
}
340-
} else if (swtPair[swtPair.size() - 1] == "read") {
341-
operation = Swt::Operation::Read;
342-
} else if (swtPair[swtPair.size() - 1] == "write") {
343-
operation = Swt::Operation::Write;
344-
if (swtPair.size() == 1) {
345-
BOOST_THROW_EXCEPTION(
346-
AlfException() << ErrorInfo::Message("Too few arguments for WRITE operation"));
347-
}
348-
} else if (swtPair[swtPair.size() - 1] == "sc_reset") {
349-
operation = Swt::Operation::SCReset;
350-
if (swtPair.size() == 2) {
351-
BOOST_THROW_EXCEPTION(
352-
AlfException() << ErrorInfo::Message("Too many arguments for SC RESET operation"));
353-
}
354-
} else if (swtPair[swtPair.size() - 1] == "wait") {
355-
operation = Swt::Operation::Wait;
356-
} else {
357-
BOOST_THROW_EXCEPTION(std::out_of_range("Parameter for SWT operation unkown"));
358385
}
359386

387+
// special handling of the write parameter
360388
if (operation == Swt::Operation::Write) {
361389
SwtWord word;
362390
word.setSize(swtWordSize);
@@ -369,7 +397,7 @@ std::pair<Swt::Operation, Swt::Data> AlfServer::stringToSwtPair(const std::strin
369397
}
370398

371399
if (hexString.length() > 19) {
372-
BOOST_THROW_EXCEPTION(std::out_of_range("Parameter does not fit in 76-bit unsigned int"));
400+
BOOST_THROW_EXCEPTION(std::out_of_range("SWT write argument does not fit in 76-bit unsigned int"));
373401
}
374402

375403
std::stringstream ss;
@@ -380,18 +408,6 @@ std::pair<Swt::Operation, Swt::Data> AlfServer::stringToSwtPair(const std::strin
380408
word.setLow(std::stoul(ss.str().substr(11, 8), NULL, 16));
381409

382410
data = word;
383-
} else if (operation == Swt::Operation::Read && swtPair.size() == 2) {
384-
try {
385-
data = std::stoi(swtPair[0]);
386-
} catch (const std::exception& e) {
387-
BOOST_THROW_EXCEPTION(SwtException() << ErrorInfo::Message("SWT Read Timeout provided cannot be converted to int"));
388-
}
389-
} else if (operation == Swt::Operation::Wait && swtPair.size() == 2) {
390-
try {
391-
data = std::stoi(swtPair[0]);
392-
} catch (const std::exception& e) {
393-
BOOST_THROW_EXCEPTION(SwtException() << ErrorInfo::Message("SWT WaitTime provided cannot be converted to int"));
394-
}
395411
}
396412

397413
return std::make_pair(operation, data);

src/Swt.cxx

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,52 @@ std::vector<SwtWord> Swt::read(SwtWord::Size wordSize, TimeOut msTimeOut)
104104
return words;
105105
}
106106

107+
std::vector<SwtWord> Swt::readMultiple(SwtWord::Size wordSize, unsigned int wordsToRead, TimeOut msTimeOut)
108+
{
109+
checkChannelSet();
110+
111+
std::vector<SwtWord> words;
112+
unsigned int readWords = 0x0;
113+
114+
while (readWords < wordsToRead) {
115+
uint32_t numWords = 0x0;
116+
117+
auto timeOut = std::chrono::steady_clock::now() + std::chrono::milliseconds(msTimeOut);
118+
bool isTimeout = false;
119+
while (!isTimeout && (numWords < 1)) {
120+
numWords = (barRead(sc_regs::SWT_MON.index) >> 16);
121+
isTimeout = std::chrono::steady_clock::now() > timeOut;
122+
}
123+
if(isTimeout){
124+
break;
125+
}
126+
127+
for (int i = 0; i < (int)numWords; i++) {
128+
SwtWord tempWord;
129+
130+
tempWord.setLow(barRead(sc_regs::SWT_RD_WORD_L.index));
131+
132+
if (wordSize == SwtWord::Size::Medium || wordSize == SwtWord::Size::High) {
133+
tempWord.setMed(barRead(sc_regs::SWT_RD_WORD_M.index));
134+
}
135+
136+
if (wordSize == SwtWord::Size::High) {
137+
tempWord.setHigh(barRead(sc_regs::SWT_RD_WORD_H.index));
138+
}
139+
140+
words.push_back(tempWord);
141+
}
142+
readWords += numWords;
143+
}
144+
145+
if (readWords != wordsToRead) {
146+
BOOST_THROW_EXCEPTION(SwtException() <<
147+
ErrorInfo::Message("ReadMultiple different number of words than expected: " + std::to_string(readWords) + " (expected " + std::to_string(wordsToRead) + ")"));
148+
}
149+
150+
return words;
151+
}
152+
107153
void Swt::write(const SwtWord& swtWord)
108154
{
109155
checkChannelSet();
@@ -122,6 +168,7 @@ void Swt::write(const SwtWord& swtWord)
122168

123169
std::vector<std::pair<Swt::Operation, Swt::Data>> Swt::executeSequence(std::vector<std::pair<Operation, Data>> sequence, bool lock, int lockTimeout)
124170
{
171+
125172
if (lock) {
126173
mLlaSession->start(lockTimeout);
127174
}
@@ -143,22 +190,32 @@ std::vector<std::pair<Swt::Operation, Swt::Data>> Swt::executeSequence(std::vect
143190
try {
144191
timeOut = boost::get<TimeOut>(data);
145192
} catch (...) { // no timeout was provided
146-
data = DEFAULT_SWT_TIMEOUT_MS;
193+
data = readTimeout;
147194
timeOut = boost::get<TimeOut>(data);
148195
}
149196
auto results = read(mSwtWordSize, timeOut);
150197

151198
for (const auto& result : results) {
152-
ret.push_back({ Operation::Read, result });
199+
ret.push_back({ operation, result });
153200
}
201+
} else if (operation == Operation::ReadMultiple) {
202+
int count;
203+
count = boost::get<int>(data);
204+
auto results = readMultiple(mSwtWordSize, count, readTimeout);
205+
for (const auto& result : results) {
206+
ret.push_back({ operation, result });
207+
}
208+
} else if (operation == Operation::SetReadTimeout) {
209+
readTimeout = boost::get<TimeOut>(data);
210+
ret.push_back({ operation, readTimeout });
154211
} else if (operation == Operation::Write) {
155212
SwtWord word = boost::get<SwtWord>(data);
156213
write(word);
157-
ret.push_back({ Operation::Write, word });
214+
ret.push_back({ operation, word });
158215
//ret.push_back({ Operation::Write, {} }); // TODO: Is it better to return {} ?
159216
} else if (operation == Operation::SCReset) {
160217
scReset();
161-
ret.push_back({ Operation::SCReset, {} });
218+
ret.push_back({ operation, {} });
162219
} else if (operation == Operation::Wait) {
163220
int waitTime;
164221
try {
@@ -208,6 +265,10 @@ std::string Swt::writeSequence(std::vector<std::pair<Operation, Data>> sequence,
208265
Data data = it.second;
209266
if (operation == Operation::Read) {
210267
resultBuffer << data << "\n";
268+
} else if (operation == Operation::ReadMultiple) {
269+
resultBuffer << data << "\n";
270+
} else if (operation == Operation::SetReadTimeout) {
271+
resultBuffer << std::dec << data << "\n";
211272
} else if (operation == Operation::Write) {
212273
resultBuffer << "0\n";
213274
} else if (operation == Operation::SCReset) {
@@ -231,6 +292,10 @@ std::string Swt::SwtOperationToString(Swt::Operation op)
231292
{
232293
if (op == Swt::Operation::Read) {
233294
return "read";
295+
} else if (op == Swt::Operation::ReadMultiple) {
296+
return "read_multiple";
297+
} else if (op == Swt::Operation::SetReadTimeout) {
298+
return "set_read_timeout";
234299
} else if (op == Swt::Operation::Write) {
235300
return "write";
236301
} else if (op == Swt::Operation::SCReset) {
@@ -250,6 +315,10 @@ Swt::Operation Swt::StringToSwtOperation(std::string op)
250315
{
251316
if (op == "read") {
252317
return Swt::Operation::Read;
318+
} else if (op == "read_multiple") {
319+
return Swt::Operation::ReadMultiple;
320+
} else if (op == "set_read_timeout") {
321+
return Swt::Operation::SetReadTimeout;
253322
} else if (op == "write") {
254323
return Swt::Operation::Write;
255324
} else if (op == "sc_reset") {

0 commit comments

Comments
 (0)