Skip to content

Commit 97755ed

Browse files
committed
[sca-mft-psu] Add support for MFT PSU SCA operations
1 parent 3efd238 commit 97755ed

File tree

11 files changed

+544
-9
lines changed

11 files changed

+544
-9
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ add_library(ALF SHARED
7777
src/Ic.cxx
7878
src/Lla.cxx
7979
src/Sca.cxx
80+
src/ScaMftPsu.cxx
8081
src/ScBase.cxx
8182
src/Swt.cxx
8283
src/SwtWord.cxx

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,18 @@ The services are DIM RPC services. Every RPC is called with a string and expects
104104
* DIM input (atomic): `lock\n0x00000010,0x00000011\n3\n0x000000020,0x00000021`
105105
* DIM output: `0x00000010,0x00000111\n3\n0x00000020,0x00000221\n`
106106

107+
##### SCA_MFT_PSU_SEQUENCE
108+
109+
This service is uniquely registered for the MFT PSU CRU.
110+
It extends the `SCA_SEQUENCE` to add the following functionality:
111+
* Parameters:
112+
* Operations:
113+
* Select master (e.g. `master`)
114+
* Select slave (e.g. `slave`)
115+
116+
* Returns:
117+
* Echo for both `master` & `slave`
118+
107119
##### SWT_SEQUENCE
108120
* Parameters:
109121
* Sequence of SWT word and operation pairs as follows:

include/Alf/Exception.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ struct ScException : AliceO2::Common::Exception {
2929
};
3030
struct ScaException : AliceO2::Common::Exception {
3131
};
32+
struct ScaMftPsuException : AliceO2::Common::Exception {
33+
};
3234
struct SwtException : AliceO2::Common::Exception {
3335
};
3436
struct IcException : AliceO2::Common::Exception {

include/Alf/ScBase.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@ class ScBase
5454
/// Executes a global SC reset
5555
void scReset();
5656

57-
/// Checks if an SCA channel has been selected
58-
/// \throws o2::alf::ScaException if no SCA channel selected
57+
/// Checks if an SC channel has been selected
58+
/// \throws o2::alf::ScException if no SC channel selected
5959
void checkChannelSet();
6060

6161
protected:
@@ -69,7 +69,7 @@ class ScBase
6969
/// Does the necessary initializations after an object creating
7070
void init(const roc::Parameters::CardIdType& cardId, int linkId);
7171

72-
/// Interface for BAR 2
72+
/// Interface for BAR 2
7373
std::shared_ptr<roc::BarInterface> mBar2;
7474
};
7575

include/Alf/Sca.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ class Sca : public ScBase
5757
SVLReset,
5858
SVLConnect,
5959
Error,
60-
Lock };
60+
Lock,
61+
Master,
62+
Slave };
6163

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

include/Alf/ScaMftPsu.h

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
/// \file ScaMftPsu.h
12+
/// \brief Definition of ALICE Lowlevel Frontend (ALF) SCA operations for the MFT PSU
13+
///
14+
/// \author Kostas Alexopoulos ([email protected])
15+
16+
#ifndef O2_ALF_INC_SCA_MFT_PSU_H
17+
#define O2_ALF_INC_SCA_MFT_PSU_H
18+
19+
#include <string>
20+
#include <map>
21+
#include <boost/variant.hpp>
22+
23+
#include "ReadoutCard/BarInterface.h"
24+
#include "ReadoutCard/Parameters.h"
25+
26+
#include "Common.h"
27+
#include "Alf/Lla.h"
28+
#include "Alf/Sca.h"
29+
#include "Alf/ScaMftPsu.h"
30+
31+
namespace roc = AliceO2::roc;
32+
33+
namespace o2
34+
{
35+
namespace alf
36+
{
37+
38+
/// Class for interfacing with the MFT PSU Slow-Control Adapter (SCA)
39+
class ScaMftPsu
40+
{
41+
public:
42+
// Pull these from Sca to simplify things a bit
43+
typedef Sca::CommandData CommandData;
44+
typedef Sca::WaitTime WaitTime;
45+
typedef Sca::Data Data;
46+
typedef Sca::Operation Operation;
47+
48+
/// Internal constructor for the AlfServer
49+
/// \param link AlfLink holding useful information coming from the AlfServer class
50+
ScaMftPsu(AlfLink link, std::shared_ptr<lla::Session> llaSession);
51+
52+
/// Executes a global SC reset
53+
void scReset();
54+
55+
/// Executes an SCA reset
56+
void svlReset();
57+
58+
/// Executes an SCA connect
59+
void svlConnect();
60+
61+
/// Changes to master
62+
void setMaster();
63+
64+
/// Changes to slave
65+
void setSlave();
66+
67+
/// Executes an SCA command
68+
/// \param commandData SCA command, data pair
69+
/// \param lock Boolean enabling implicit locking
70+
/// \throws o2::lla::LlaException on lock fail,
71+
/// o2::alf::ScaMftPsuException on SCA error
72+
CommandData executeCommand(CommandData commandData, bool lock = false)
73+
{
74+
return executeCommand(commandData.command, commandData.data, lock);
75+
}
76+
/// Executes an SCA command
77+
/// \param command SCA command
78+
/// \param data SCA data
79+
/// \param lock Boolean enabling implicit locking
80+
/// \throws o2::lla::LlaException on lock fail
81+
/// o2::alf::ScaMftPsuException on SCA error
82+
CommandData executeCommand(uint32_t command, uint32_t data, bool lock = false);
83+
84+
/// Executes an SCA sequence
85+
/// \param operations A vector of Operation and Data pairs
86+
/// \param lock Boolean enabling implicit locking
87+
/// \return A vector of Operation and Data pairs
88+
/// CommandData for Commands
89+
/// WaitTime for Waits
90+
/// std::string for Errors
91+
/// \throws o2::lla::LlaException on lock fail
92+
std::vector<std::pair<Operation, Data>> executeSequence(const std::vector<std::pair<Operation, Data>>& operations, bool lock = false);
93+
94+
/// Executes an SCA sequence for the ALF Server
95+
/// \param operations A vector of Data and Operation pairs
96+
/// \param lock Boolean enabling implicit locking
97+
/// \return A string of newline separated results;
98+
/// \throws o2::lla::LlaException on lock fail
99+
/// o2::alf::ScaMftPsuException on invalid operation or error
100+
std::string writeSequence(const std::vector<std::pair<Operation, Data>>& operations, bool lock = false);
101+
102+
private:
103+
uint32_t barRead(uint32_t index);
104+
void barWrite(uint32_t index, uint32_t data);
105+
106+
/// Performs an SCA read
107+
/// \return CommandData An SCA command, data pair
108+
/// \throws o2::alf::ScaMftPsuException on SCA error
109+
CommandData read();
110+
111+
/// Performs an SCA write
112+
/// \param command SCA command
113+
/// \param data SCA data
114+
/// \throws o2::alf::ScaMftPsuException on SCA error
115+
void write(uint32_t command, uint32_t data);
116+
117+
/// Performs an SCA write
118+
/// \param commandData SCA command, data pair
119+
/// \throws o2::alf::ScaMftPsuException on SCA error
120+
void write(CommandData commandData)
121+
{
122+
write(commandData.command, commandData.data);
123+
};
124+
void execute();
125+
void checkError(uint32_t command);
126+
bool isChannelBusy(uint32_t command);
127+
void waitOnBusyClear();
128+
129+
/// Interface for BAR 2
130+
std::shared_ptr<roc::BarInterface> mBar2;
131+
AlfLink mLink;
132+
std::unique_ptr<LlaSession> mLlaSession;
133+
134+
static constexpr int DEFAULT_SCA_WAIT_TIME_MS = 3;
135+
};
136+
137+
} // namespace alf
138+
} // namespace o2
139+
140+
#endif // O2_ALF_INC_SCA_H

src/AlfServer.cxx

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,21 @@ std::string AlfServer::scaBlobWrite(const std::string& parameter, AlfLink link)
9494
return sca.writeSequence(scaPairs, lock);
9595
}
9696

97+
std::string AlfServer::scaMftPsuBlobWrite(const std::string& parameter, AlfLink link)
98+
{
99+
std::vector<std::string> stringPairs = Util::split(parameter, argumentSeparator());
100+
std::vector<std::pair<Sca::Operation, Sca::Data>> scaPairs = parseStringToScaPairs(stringPairs);
101+
ScaMftPsu sca = ScaMftPsu(link, mSessions[link.serialId]);
102+
103+
bool lock = false;
104+
// Check if the operation should be locked
105+
if (scaPairs[0].first == Sca::Operation::Lock) {
106+
scaPairs.erase(scaPairs.begin());
107+
lock = true;
108+
}
109+
return sca.writeSequence(scaPairs, lock);
110+
}
111+
97112
std::string AlfServer::swtBlobWrite(const std::string& parameter, AlfLink link)
98113
{
99114

@@ -311,6 +326,18 @@ std::pair<Sca::Operation, Sca::Data> AlfServer::stringToScaPair(const std::strin
311326
BOOST_THROW_EXCEPTION(
312327
AlfException() << ErrorInfo::Message("Too many arguments for SC RESET operation"));
313328
}
329+
} else if (scaPair[scaPair.size() - 1] == "master") {
330+
operation = Sca::Operation::Master;
331+
if (scaPair.size() != 1) {
332+
BOOST_THROW_EXCEPTION(
333+
AlfException() << ErrorInfo::Message("Too many arguments for MASTER operation"));
334+
}
335+
} else if (scaPair[scaPair.size() - 1] == "slave") {
336+
operation = Sca::Operation::Slave;
337+
if (scaPair.size() != 1) {
338+
BOOST_THROW_EXCEPTION(
339+
AlfException() << ErrorInfo::Message("Too many arguments for SLAVE operation"));
340+
}
314341
} else { // regular sca command
315342
operation = Sca::Operation::Command;
316343
if (scaPair.size() != 2) {
@@ -548,6 +575,18 @@ void AlfServer::makeRpcServers(std::vector<AlfLink> links)
548575
std::shared_ptr<roc::BarInterface> bar = link.bar;
549576

550577
if (link.cardType == roc::CardType::Cru) {
578+
lla::SessionParameters params = lla::SessionParameters::makeParameters()
579+
.setSessionName("ALF")
580+
.setCardId(link.serialId);
581+
mSessions[link.serialId] = std::make_shared<lla::Session>(params);
582+
583+
if (kMftPsuSerials.find(link.serialId.getSerial()) != kMftPsuSerials.end()) {
584+
// SCA MFT PSU Sequence
585+
servers.push_back(makeServer(names.scaMftPsuSequence(),
586+
[link, this](auto parameter) { return scaMftPsuBlobWrite(parameter, link); }));
587+
continue;
588+
}
589+
551590
if (link.linkId == 0 && link.serialId.getEndpoint() == 0) { // Services per card
552591
// Register Read
553592
servers.push_back(makeServer(names.registerRead(),
@@ -569,11 +608,6 @@ void AlfServer::makeRpcServers(std::vector<AlfLink> links)
569608
[link, this](auto parameter) { return llaSessionStop(parameter, link.serialId); }));
570609
}
571610

572-
lla::SessionParameters params = lla::SessionParameters::makeParameters()
573-
.setSessionName("ALF")
574-
.setCardId(link.serialId);
575-
mSessions[link.serialId] = std::make_shared<lla::Session>(params);
576-
577611
// SCA Sequence
578612
servers.push_back(makeServer(names.scaSequence(),
579613
[link, this](auto parameter) { return scaBlobWrite(parameter, link); }));

src/AlfServer.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121
#include <chrono>
2222
#include <iomanip>
2323
#include <thread>
24+
#include <unordered_set>
2425

2526
#include "Alf/Exception.h"
2627
#include "DimServices/DimServices.h"
2728
#include "Alf/Common.h"
2829
#include "Alf/Ic.h"
2930
#include "Alf/Sca.h"
31+
#include "Alf/ScaMftPsu.h"
3032
#include "Alf/Swt.h"
3133

3234
#include "Lla/Lla.h"
@@ -50,6 +52,7 @@ class AlfServer
5052
static std::string registerRead(const std::string& parameter, std::shared_ptr<roc::BarInterface>);
5153
static std::string registerWrite(const std::string& parameter, std::shared_ptr<roc::BarInterface>);
5254
std::string scaBlobWrite(const std::string& parameter, AlfLink link);
55+
std::string scaMftPsuBlobWrite(const std::string& parameter, AlfLink link);
5356
std::string swtBlobWrite(const std::string& parameter, AlfLink link);
5457
std::string icBlobWrite(const std::string& parameter, AlfLink link);
5558
std::string icGbtI2cWrite(const std::string& parameter, AlfLink link);
@@ -76,6 +79,8 @@ class AlfServer
7679
/// serialId -> link -> vector of RPC servers
7780
std::map<roc::SerialId, std::map<int, std::vector<std::unique_ptr<StringRpcServer>>>, serialIdComparator> mRpcServers;
7881
std::map<roc::SerialId, std::shared_ptr<lla::Session>, serialIdComparator> mSessions;
82+
83+
const std::unordered_set<int> kMftPsuSerials = { 0000, 0553 };
7984
};
8085

8186
} // namespace alf

src/DimServices/ServiceNames.cxx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
/// \brief Implementation of DIM service names
1313
///
1414
/// \author Pascal Boeschoten ([email protected])
15+
/// \author Kostas Alexopoulos ([email protected]))
1516

1617
#include <boost/format.hpp>
1718

@@ -41,6 +42,7 @@ DEFCARDSERVICENAME(registerRead, "REGISTER_READ")
4142
DEFCARDSERVICENAME(registerWrite, "REGISTER_WRITE")
4243

4344
DEFLINKSERVICENAME(scaSequence, "SCA_SEQUENCE")
45+
DEFLINKSERVICENAME(scaMftPsuSequence, "SCA_MFT_PSU_SEQUENCE")
4446
DEFLINKSERVICENAME(swtSequence, "SWT_SEQUENCE")
4547
DEFLINKSERVICENAME(icSequence, "IC_SEQUENCE")
4648
DEFLINKSERVICENAME(icGbtI2cWrite, "IC_GBT_I2C_WRITE")

src/DimServices/ServiceNames.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class ServiceNames
3636
std::string registerRead() const;
3737
std::string registerWrite() const;
3838
std::string scaSequence() const;
39+
std::string scaMftPsuSequence() const;
3940
std::string swtSequence() const;
4041
std::string icSequence() const;
4142
std::string icGbtI2cWrite() const;

0 commit comments

Comments
 (0)