Skip to content

Commit 7cfc40e

Browse files
committed
[alf] Introduce implicit locking option for SC sequence services
1 parent ae062d1 commit 7cfc40e

File tree

7 files changed

+89
-20
lines changed

7 files changed

+89
-20
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,14 @@ The services are DIM RPC services. Every RPC is called with a string and expects
8080
* Operations may be:
8181
* An SCA command and data pair (e.g. `0x0000f00d,0x0000cafe`)
8282
* A wait operation (e.g. `30,wait`)
83+
* An instruction to execute the sequence atomically (`lock` - needs to lead the sequence)
8384
* Returns:
8485
* Sequence of SCA command and SCA read pairs, and wait confirmations
86+
* No entries for `lock` directives
8587

8688
* Example:
8789
* DIM input: `0x00000010,0x00000011\n3\n0x000000020,0x00000021`
90+
* DIM input (atomic): `lock\n0x00000010,0x00000011\n3\n0x000000020,0x00000021`
8891
* DIM output: `0x00000010,0x00000111\n3\n0x00000020,0x00000221\n`
8992

9093
##### SWT_SEQUENCE
@@ -94,14 +97,17 @@ The services are DIM RPC services. Every RPC is called with a string and expects
9497
* `write` with SWT prefix (e.g. `0x0000f00d,write`)
9598
* `reset` (without SWT word)
9699
* `read` with optional TimeOut prefix (e.g. `2,read`)
100+
* `lock` which instructs ALF to execute the sequence atomically (needs to lead the sequence)
97101
* Returns:
98102
* Sequence of SWT output as follows:
99103
* `write` always retuns `0`
100104
* `read` returns the SWT words present in the CRU SWT FIFO
101105
* `reset` returns nothing
106+
* `lock` returns nothing
102107

103108
* Example:
104109
* DIM input `reset\n0x0000000000badc0ffee,write\nread\n0xbadf00d,write\n4,read`
110+
* DIM input (atomic) `lock\nreset\n0x0000000000badc0ffee,write\nread\n0xbadf00d,write\n4,read`
105111
* DIM output `0\n0x0000000000badc0ffee\n0\n0x000000000000badf00d\n`
106112

107113
##### IC_SEQUENCE
@@ -111,13 +117,16 @@ The services are DIM RPC services. Every RPC is called with a string and expects
111117
* Operations may be:
112118
* Address, Value and `write`
113119
* Address and `read`
120+
* `lock` which instructs ALF to execute the sequence atomically (needs to lead the sequence)
114121

115122
* Returns:
116123
* Value on `write` (echo)
117124
* Value on `read`
125+
* Nothing on `lock`
118126

119127
* Example:
120128
* DIM input: `0x54,0xff,write\n0x54,read`
129+
* DIM input (atomic): `lock\n0x54,0xff,write\n0x54,read`
121130
* DIM output: `0x000000ff\n0x000000ff\n`
122131

123132
##### IC_GBT_I2C_WRITE

apps/AlfClient.cxx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ class AlfClient : public AliceO2::Common::Program
152152
Logger::get().log() << "[REGISTER] Wrote: " << Util::formatValue(wValue) << " Read: " << Util::formatValue(rValue) << endm;
153153

154154
if (mOptions.swt) {
155-
auto swtOut = swtSequence.write({ std::make_pair("0x0000000000000000000", "write"),
155+
auto swtOut = swtSequence.write({ std::make_pair("", "lock"),
156+
std::make_pair("0x0000000000000000000", "write"),
156157
std::make_pair("", "reset"),
157158
std::make_pair("0x0000000000000000000", "write"),
158159
std::make_pair("0x000000001234", "write"),

include/Alf/Ic.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class Ic
4747
public:
4848
/// Struct holding the IC address and data pair; useful to AlfServer
4949
struct IcData {
50-
uint32_t address;
50+
uint32_t address = 0x0;
5151
uint32_t data = 0x0;
5252
};
5353

@@ -115,7 +115,8 @@ class Ic
115115
/// Enum for the different IC operation types
116116
enum Operation { Read,
117117
Write,
118-
Error };
118+
Error,
119+
Lock };
119120

120121
/// Executes an IC sequence
121122
/// \param ops A vector of Data and Operations pairs

include/Alf/Sca.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ class Sca
5252
/// Enum for the different SCA operation types as seen from DIM RPCs
5353
enum Operation { Command,
5454
Wait,
55-
Error };
55+
Error,
56+
Lock };
5657

5758
/// Internal constructor for the AlfServer
5859
/// \param link AlfLink holding useful information coming from the AlfServer class

include/Alf/Swt.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ class Swt
5858
enum Operation { Read,
5959
Write,
6060
Reset,
61-
Error };
61+
Error,
62+
Lock };
6263

6364
/// Internal constructor for the ALF server
6465
/// \param link AlfLink holding useful information coming from the AlfServer class

src/AlfClient.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,11 @@ class ScaSequenceRpc : DimRpcInfoWrapper
135135
{
136136
std::stringstream buffer;
137137
for (size_t i = 0; i < sequence.size(); ++i) {
138-
buffer << sequence[i].first << pairSeparator() << sequence[i].second;
138+
if (sequence[i].first != "") {
139+
buffer << sequence[i].first << pairSeparator() << sequence[i].second;
140+
} else {
141+
buffer << sequence[i].second;
142+
}
139143
if (i + 1 < sequence.size()) {
140144
buffer << argumentSeparator();
141145
}
@@ -246,7 +250,11 @@ class IcSequenceRpc : DimRpcInfoWrapper
246250
{
247251
std::stringstream buffer;
248252
for (size_t i = 0; i < sequence.size(); ++i) {
249-
buffer << sequence[i].first << pairSeparator() << sequence[i].second;
253+
if (sequence[i].first != "") {
254+
buffer << sequence[i].first << pairSeparator() << sequence[i].second;
255+
} else {
256+
buffer << sequence[i].second;
257+
}
250258
if (i + 1 < sequence.size()) {
251259
buffer << argumentSeparator();
252260
}

src/AlfServer.cxx

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,14 @@ std::string AlfServer::scaBlobWrite(const std::string& parameter, AlfLink link)
8484
std::vector<std::string> stringPairs = Util::split(parameter, argumentSeparator());
8585
std::vector<std::pair<Sca::Operation, Sca::Data>> scaPairs = parseStringToScaPairs(stringPairs);
8686
Sca sca = Sca(link);
87-
return sca.writeSequence(scaPairs);
87+
88+
bool lock = false;
89+
// Check if the operation should be locked
90+
if (scaPairs[0].first == Sca::Operation::Lock) {
91+
scaPairs.erase(scaPairs.begin());
92+
lock = true;
93+
}
94+
return sca.writeSequence(scaPairs, lock);
8895
}
8996

9097
std::string AlfServer::swtBlobWrite(const std::string& parameter, AlfLink link)
@@ -93,7 +100,14 @@ std::string AlfServer::swtBlobWrite(const std::string& parameter, AlfLink link)
93100
std::vector<std::string> stringPairs = Util::split(parameter, argumentSeparator());
94101
std::vector<std::pair<Swt::Operation, Swt::Data>> swtPairs = parseStringToSwtPairs(stringPairs);
95102
Swt swt = Swt(link);
96-
return swt.writeSequence(swtPairs);
103+
104+
bool lock = false;
105+
// Check if the operation should be locked
106+
if (swtPairs[0].first == Swt::Operation::Lock) {
107+
swtPairs.erase(swtPairs.begin());
108+
lock = true;
109+
}
110+
return swt.writeSequence(swtPairs, lock);
97111
}
98112

99113
std::string AlfServer::icBlobWrite(const std::string& parameter, AlfLink link)
@@ -102,7 +116,14 @@ std::string AlfServer::icBlobWrite(const std::string& parameter, AlfLink link)
102116
std::vector<std::string> stringPairs = Util::split(parameter, argumentSeparator());
103117
std::vector<std::pair<Ic::Operation, Ic::Data>> icPairs = parseStringToIcPairs(stringPairs);
104118
Ic ic = Ic(link);
105-
return ic.writeSequence(icPairs);
119+
120+
bool lock = false;
121+
// Check if the operation should be locked
122+
if (icPairs[0].first == Ic::Operation::Lock) {
123+
icPairs.erase(icPairs.begin());
124+
lock = true;
125+
}
126+
return ic.writeSequence(icPairs, lock);
106127
}
107128

108129
std::string AlfServer::icGbtI2cWrite(const std::string& parameter, AlfLink link)
@@ -249,23 +270,38 @@ std::vector<uint32_t> AlfServer::stringToRegisterPair(const std::string stringPa
249270
std::pair<Sca::Operation, Sca::Data> AlfServer::stringToScaPair(const std::string stringPair)
250271
{
251272
std::vector<std::string> scaPair = Util::split(stringPair, pairSeparator());
252-
if (scaPair.size() != 2) {
253-
BOOST_THROW_EXCEPTION(
254-
AlfException() << ErrorInfo::Message("SCA command-data pair not formatted correctly"));
255-
}
256273

257274
Sca::Data data;
258275
Sca::Operation operation;
259276

260-
if (scaPair[scaPair.size() - 1] == "wait") {
277+
if (scaPair.size() < 1 || scaPair.size() > 2) {
278+
BOOST_THROW_EXCEPTION(
279+
AlfException() << ErrorInfo::Message("SCA command-data pair not formatted correctly"));
280+
}
281+
282+
if (scaPair[scaPair.size() - 1] == "lock") {
283+
operation = Sca::Operation::Lock;
284+
if (scaPair.size() != 1) {
285+
BOOST_THROW_EXCEPTION(
286+
AlfException() << ErrorInfo::Message("Too many arguments for LOCK operation"));
287+
}
288+
} else if (scaPair[scaPair.size() - 1] == "wait") {
261289
operation = Sca::Operation::Wait;
290+
if (scaPair.size() != 2) {
291+
BOOST_THROW_EXCEPTION(
292+
AlfException() << ErrorInfo::Message("Too few arguments for WAIT operation"));
293+
}
262294
try {
263295
data = std::stoi(scaPair[0]);
264296
} catch (const std::exception& e) {
265297
BOOST_THROW_EXCEPTION(SwtException() << ErrorInfo::Message("SCA Wait Time provided cannot be converted to int"));
266298
}
267299
} else { // regular sca command
268300
operation = Sca::Operation::Command;
301+
if (scaPair.size() != 2) {
302+
BOOST_THROW_EXCEPTION(
303+
AlfException() << ErrorInfo::Message("Too few arguments for SCA command-data pair"));
304+
}
269305
Sca::CommandData commandData;
270306
commandData.command = Util::stringToHex(scaPair[0]);
271307
commandData.data = Util::stringToHex(scaPair[1]);
@@ -286,7 +322,13 @@ std::pair<Swt::Operation, Swt::Data> AlfServer::stringToSwtPair(const std::strin
286322

287323
Swt::Operation operation;
288324

289-
if (swtPair[swtPair.size() - 1] == "read") {
325+
if (swtPair[swtPair.size() - 1] == "lock") {
326+
operation = Swt::Operation::Lock;
327+
if (swtPair.size() == 2) {
328+
BOOST_THROW_EXCEPTION(
329+
AlfException() << ErrorInfo::Message("Too many arguments for LOCK operation"));
330+
}
331+
} else if (swtPair[swtPair.size() - 1] == "read") {
290332
operation = Swt::Operation::Read;
291333
} else if (swtPair[swtPair.size() - 1] == "write") {
292334
operation = Swt::Operation::Write;
@@ -342,15 +384,23 @@ std::pair<Swt::Operation, Swt::Data> AlfServer::stringToSwtPair(const std::strin
342384
std::pair<Ic::Operation, Ic::Data> AlfServer::stringToIcPair(const std::string stringPair)
343385
{
344386
std::vector<std::string> icPair = Util::split(stringPair, pairSeparator());
345-
if (icPair.size() != 2 && icPair.size() != 3) {
387+
if (icPair.size() < 1 || icPair.size() > 3) {
346388
BOOST_THROW_EXCEPTION(
347389
AlfException() << ErrorInfo::Message("IC pair not formatted correctly"));
348390
}
349391

350392
Ic::Operation icOperation;
393+
Ic::IcData icData;
351394

352395
// Parse IC operation
353-
if (icPair[icPair.size() - 1] == "read") {
396+
if (icPair[icPair.size() - 1] == "lock") {
397+
icOperation = Ic::Operation::Lock;
398+
if (icPair.size() > 1) {
399+
BOOST_THROW_EXCEPTION(
400+
AlfException() << ErrorInfo::Message("Too many arguments for LOCK operation"));
401+
}
402+
return std::make_pair(icOperation, icData); // no data to parse, return immediately
403+
} else if (icPair[icPair.size() - 1] == "read") {
354404
icOperation = Ic::Operation::Read;
355405
if (icPair.size() == 3) {
356406
BOOST_THROW_EXCEPTION(
@@ -398,8 +448,6 @@ std::pair<Ic::Operation, Ic::Data> AlfServer::stringToIcPair(const std::string s
398448
}
399449
}
400450

401-
Ic::IcData icData;
402-
403451
std::stringstream ss;
404452
ss << std::setw(4) << std::setfill('0') << hexAddress;
405453

0 commit comments

Comments
 (0)