Skip to content

Commit 062fa66

Browse files
authored
Merge pull request #419 from sy-c/master
pat-player
2 parents 836352b + c246b15 commit 062fa66

File tree

7 files changed

+364
-229
lines changed

7 files changed

+364
-229
lines changed

cmake/ReadoutCardConfig.cmake.in

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,9 @@ set(Monitoring_CMAKE_DIR @Monitoring_DIR@)
2020
set(InfoLogger_CMAKE_DIR @InfoLogger_ROOT@)
2121

2222
if(NOT APPLE)
23-
find_package(Python3 3.6 COMPONENTS Interpreter Development)
23+
find_package(Python3 3.6 COMPONENTS Interpreter Development)
2424
if(Python3_FOUND)
2525
set(boost_python_component "python${Python3_VERSION_MAJOR}${Python3_VERSION_MINOR}")
26-
else()
27-
# Backwards compatible. Can be removed once the Python3 recipe is stable
28-
message(WARNING "Python 3 was not found: falling back to Python 3")
29-
find_package(Python2 2.7 COMPONENTS Development REQUIRED)
30-
set(boost_python_component "python27")
3126
endif()
3227
endif()
3328

doc/releaseNotes.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,7 @@ This file describes the main feature changes for released versions of ReadoutCar
6666
- Fix registers for FEC status counters.
6767
- Updated list of firmwares for CRORC
6868
- CMake cleanup: removed python2 support.
69+
70+
## v0.45.0 - 03/10/2023
71+
- o2-roc-pat-player: options have changed to match the [latest firmware conventions](https://gitlab.cern.ch/alice-cru/cru-fw/-/tree/pplayer/TTC#address-table). Values can specified as decimal or hexadecimal numbers.
72+
- Added support for pattern-player configuration parsing (used by ALF).

include/ReadoutCard/PatternPlayer.h

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,43 +33,47 @@ class PatternPlayer
3333
{
3434
public:
3535
struct Info {
36-
uint128_t syncPattern = 0x0;
37-
uint128_t resetPattern = 0x0;
38-
uint128_t idlePattern = 0x0;
39-
uint32_t syncLength = 1;
40-
uint32_t syncDelay = 0;
41-
uint32_t resetLength = 1;
42-
uint32_t resetTriggerSelect = 30;
43-
uint32_t syncTriggerSelect = 29;
44-
bool syncAtStart = false;
45-
bool triggerSync = false;
46-
bool triggerReset = false;
36+
// as defined in https://gitlab.cern.ch/alice-cru/cru-fw/-/tree/pplayer/TTC#address-table
37+
uint128_t pat0= 0x0;
38+
uint128_t pat1 = 0x0;
39+
uint128_t pat2 = 0x0;
40+
uint128_t pat3 = 0x0;
41+
uint32_t pat1Length = 1;
42+
uint32_t pat1Delay = 0;
43+
uint32_t pat2Length = 1;
44+
uint32_t pat3Length = 1;
45+
uint32_t pat1TriggerSelect = 29;
46+
uint32_t pat2TriggerSelect = 30;
47+
uint32_t pat3TriggerSelect = 0;
48+
uint32_t pat2TriggerTF = 0;
49+
50+
bool exePat1AtStart = false;
51+
bool exePat1Now = false;
52+
bool exePat2Now = false;
4753
};
4854

4955
PatternPlayer(std::shared_ptr<BarInterface> bar);
5056
void play(PatternPlayer::Info info);
5157
PatternPlayer::Info read();
5258

59+
// helper function to fill Info fields from string
60+
// 128-bit string parser (both hex and decimal)
61+
// nBits specifies the maximum allowed bit width
62+
// name is used in the error message, if any
63+
// throws exception on error
64+
static uint128_t getValueFromString(const std::string &s, unsigned int nBits = 128, const std::string &name = "");
65+
66+
// parse a vector of strings into an Info struct
67+
// strings with # are considered as comments and not used
68+
// number of valid strings must match exactly number of parameters in struct
69+
// throws an exception on error
70+
static PatternPlayer::Info getInfoFromString(const std::vector<std::string> &parameters);
71+
5372
private:
5473
void configure(bool startConfig);
55-
void setIdlePattern(uint128_t pattern);
56-
void setSyncPattern(uint128_t pattern);
57-
void configureSync(uint32_t length = 1, uint32_t delay = 0);
58-
void setResetPattern(uint128_t pattern);
59-
void configureReset(uint32_t length = 1);
60-
void selectPatternTrigger(uint32_t syncTrigger = 3, uint32_t resetTrigger = 3);
61-
void enableSyncAtStart(bool enable = false);
62-
void triggerSync();
63-
void triggerReset();
64-
65-
uint128_t getSyncPattern();
66-
uint128_t getResetPattern();
67-
uint128_t getIdlePattern();
68-
uint32_t getSyncLength();
69-
uint32_t getSyncDelay();
70-
uint32_t getResetLength();
71-
uint32_t getResetTriggerSelect();
72-
uint32_t getSyncTriggerSelect();
74+
void exePat1AtStart(bool enable = false);
75+
void exePat1();
76+
void exePat2();
7377

7478
std::shared_ptr<BarInterface> mBar;
7579
};

src/CommandLineUtilities/ProgramPatternPlayer.cxx

Lines changed: 91 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
1+
22
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
33
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
44
// All rights not expressly granted are reserved.
@@ -32,59 +32,51 @@ using namespace o2::roc;
3232
namespace po = boost::program_options;
3333
using namespace boost::multiprecision;
3434

35+
3536
class ProgramPatternPlayer : public Program
3637
{
3738
public:
3839
virtual Description getDescription()
3940
{
4041
return { "PatternPlayer", "Configure the CRU pattern player",
41-
"o2-roc-pat-player --id 42:00.0 --sync 0x0123457899876543210abcdefedcb --sync-length 4 --sync-delay 2 --sync-at-start\n" };
42+
"o2-roc-pat-player --id 42:00.0 --pat1 0x012345789abdef0123 --pat1-length 4 --pat1-delay 2 --execute-pat1-at-start\n" };
4243
}
4344

4445
virtual void addOptions(boost::program_options::options_description& options)
4546
{
4647
Options::addOptionCardId(options);
47-
options.add_options()("sync",
48-
po::value<std::string>(&mOptions.syncPattern)->default_value("0x0"),
49-
"80-bit sync pattern in hex");
50-
options.add_options()("reset",
51-
po::value<std::string>(&mOptions.resetPattern)->default_value("0x0"),
52-
"80-bit reset pattern in hex");
53-
options.add_options()("idle",
54-
po::value<std::string>(&mOptions.idlePattern)->default_value("0x0"),
55-
"80-bit idle pattern in hex");
56-
options.add_options()("sync-length",
57-
po::value<uint32_t>(&mOptions.syncLength)->default_value(1),
58-
"Sync pattern's length");
59-
options.add_options()("sync-delay",
60-
po::value<uint32_t>(&mOptions.syncDelay)->default_value(0),
61-
"Sync pattern's delay");
62-
options.add_options()("reset-length",
63-
po::value<uint32_t>(&mOptions.resetLength)->default_value(1),
64-
"Reset pattern's length");
65-
options.add_options()("reset-trigger-select",
66-
po::value<uint32_t>(&mOptions.resetTriggerSelect)->default_value(30),
67-
"Select trigger for SYNC from TTC_DATA[0-31]");
68-
options.add_options()("sync-trigger-select",
69-
po::value<uint32_t>(&mOptions.syncTriggerSelect)->default_value(29),
70-
"Select trigger for RESET from TTC_DATA[0-31]");
71-
options.add_options()("sync-at-start",
72-
po::bool_switch(&mOptions.syncAtStart)->default_value(false),
73-
"Enable automatically sending a sync pattern when runenable goes high");
74-
options.add_options()("trigger-sync",
75-
po::bool_switch(&mOptions.triggerSync)->default_value(false),
76-
"Manually trigger the SYNC pattern");
77-
options.add_options()("trigger-reset",
78-
po::bool_switch(&mOptions.triggerReset)->default_value(false),
79-
"Manually trigger the reset pattern");
48+
49+
optionValues.reserve(16); // need to keep same variable addresses
50+
51+
addOptionValue(options, "pat0", "80-bit pat0 pattern", &mOptions.info.pat0, 80);
52+
addOptionValue(options, "pat1", "80-bit pat1 pattern", &mOptions.info.pat1, 80);
53+
addOptionValue(options, "pat2", "80-bit pat2 pattern", &mOptions.info.pat2, 80);
54+
addOptionValue(options, "pat3", "80-bit pat3 pattern", &mOptions.info.pat3, 80);
55+
addOptionValue(options, "pat1-length", "pat1 pattern's length", &mOptions.info.pat1Length);
56+
addOptionValue(options, "pat1-delay", "pat1 pattern's delay", &mOptions.info.pat1Delay);
57+
addOptionValue(options, "pat2-length", "pat2 pattern's length", &mOptions.info.pat2Length);
58+
addOptionValue(options, "pat2-trigger-counters", "Trigger counters for pat2: TF[31:20] ORBIT[19:12] BC[11:0]", &mOptions.info.pat2TriggerTF);
59+
addOptionValue(options, "pat3-length", "pat3 pattern's length", &mOptions.info.pat3Length);
60+
addOptionValue(options, "pat1-trigger-select", "Select trigger for pat1", &mOptions.info.pat1TriggerSelect);
61+
addOptionValue(options, "pat2-trigger-select", "Select trigger for pat2", &mOptions.info.pat2TriggerSelect);
62+
addOptionValue(options, "pat3-trigger-select", "Select trigger for pat3", &mOptions.info.pat3TriggerSelect);
63+
64+
options.add_options()("execute-pat1-at-start",
65+
po::bool_switch(&mOptions.info.exePat1AtStart)->default_value(false),
66+
"Enable automatically sending a pat1 pattern when runenable goes high");
67+
options.add_options()("execute-pat1-now",
68+
po::bool_switch(&mOptions.info.exePat1Now)->default_value(false),
69+
"Manually trigger the pat1 pattern now");
70+
options.add_options()("execute-pat2-now",
71+
po::bool_switch(&mOptions.info.exePat2Now)->default_value(false),
72+
"Manually trigger the pat2 pattern now");
8073
options.add_options()("read-back",
8174
po::bool_switch(&mOptions.readBack)->default_value(false),
8275
"Reads back the pattern player configuration [DOES NOT CONFIGURE!!]");
8376
}
8477

8578
virtual void run(const boost::program_options::variables_map& map)
8679
{
87-
8880
auto cardId = Options::getOptionCardId(map);
8981
auto params = Parameters::makeParameters(cardId, 2);
9082
auto bar2 = ChannelFactory().getBar(params);
@@ -98,47 +90,80 @@ class ProgramPatternPlayer : public Program
9890
return;
9991
}
10092

93+
// convert input strings to numbers
94+
parseOptionValues();
95+
10196
auto cruBar2 = std::dynamic_pointer_cast<CruBar>(bar2);
10297
if (!mOptions.readBack) {
103-
cruBar2->patternPlayer({ uint128_t(mOptions.syncPattern), //TODO: Parse this correctly!
104-
uint128_t(mOptions.resetPattern),
105-
uint128_t(mOptions.idlePattern),
106-
mOptions.syncLength,
107-
mOptions.syncDelay,
108-
mOptions.resetLength,
109-
mOptions.resetTriggerSelect,
110-
mOptions.syncTriggerSelect,
111-
mOptions.syncAtStart,
112-
mOptions.triggerSync,
113-
mOptions.triggerReset });
98+
cruBar2->patternPlayer(mOptions.info);
11499
} else {
115100
auto ppInfo = cruBar2->patternPlayerRead();
116-
std::cout << "sync pattern:\t\t0x" << std::hex << ppInfo.syncPattern << std::endl;
117-
std::cout << "reset pattern:\t\t0x" << ppInfo.resetPattern << std::endl;
118-
std::cout << "idle pattern:\t\t0x" << ppInfo.idlePattern << std::dec << std::endl;
119-
std::cout << "sync length:\t\t" << ppInfo.syncLength << std::endl;
120-
std::cout << "sync delay:\t\t" << ppInfo.syncDelay << std::endl;
121-
std::cout << "reset length:\t\t" << ppInfo.resetLength << std::endl;
122-
std::cout << "reset trigger select:\t" << ppInfo.resetTriggerSelect << std::endl;
123-
std::cout << "sync trigger select:\t" << ppInfo.syncTriggerSelect << std::endl;
101+
std::cout << "pat0 pattern:\t\t0x" << std::hex << ppInfo.pat0 << std::endl;
102+
std::cout << "pat1 pattern:\t\t0x" << std::hex << ppInfo.pat1 << std::endl;
103+
std::cout << "pat2 pattern:\t\t0x" << std::hex << ppInfo.pat2 << std::endl;
104+
std::cout << "pat3 pattern:\t\t0x" << std::hex << ppInfo.pat3 << std::endl;
105+
106+
std::cout << "pat1 length:\t\t" << std::dec << ppInfo.pat1Length << std::endl;
107+
std::cout << "pat1 delay:\t\t" << std::dec << ppInfo.pat1Delay << std::endl;
108+
std::cout << "pat2 length:\t\t" << std::dec << ppInfo.pat2Length << std::endl;
109+
std::cout << "pat3 length:\t\t" << std::dec << ppInfo.pat3Length << std::endl;
110+
111+
std::cout << "pat1 trigger select:\t0x" << std::hex << ppInfo.pat1TriggerSelect << std::endl;
112+
std::cout << "pat2 trigger select:\t0x" << std::hex << ppInfo.pat2TriggerSelect << std::endl;
113+
std::cout << "pat3 trigger select:\t0x" << std::hex << ppInfo.pat3TriggerSelect << std::endl;
114+
115+
std::cout << "pat2 trigger counters:\t"
116+
<< "TF 0x" << std::hex << ((ppInfo.pat2TriggerTF >> 20) & 0xFFF)
117+
<< " ORBIT 0x" << std::hex << ((ppInfo.pat2TriggerTF >> 12) & 0xFF)
118+
<< " BC 0x" << std::hex << (ppInfo.pat2TriggerTF & 0xFFF)
119+
<< std::endl;
124120
}
125121
}
126122

127123
private:
128124
struct OptionsStruct {
129-
std::string syncPattern = "0x0";
130-
std::string resetPattern = "0x0";
131-
std::string idlePattern = "0x0";
132-
uint32_t syncLength = 1;
133-
uint32_t syncDelay = 0;
134-
uint32_t resetLength = 1;
135-
uint32_t resetTriggerSelect = 30;
136-
uint32_t syncTriggerSelect = 29;
137-
bool syncAtStart = false;
138-
bool triggerSync = false;
139-
bool triggerReset = false;
125+
PatternPlayer::Info info;
140126
bool readBack = false;
141127
} mOptions;
128+
129+
struct OptionValue {
130+
public:
131+
enum OptionValueType {UINT32, UINT64, UINT128};
132+
std::string name; // option name
133+
std::string value; // string value
134+
void * destination; // variable assigned when parsing value
135+
unsigned int bitWidth; // maximum bit width allowed
136+
OptionValueType type; // variable type
137+
}; // namespace option
138+
139+
std::vector<OptionValue> optionValues;
140+
141+
// register 32bit option value
142+
void addOptionValue(boost::program_options::options_description& options, const char *name, const char *description, uint32_t *destinationVariable, unsigned int bitWidth = 32) {
143+
optionValues.push_back({name, "", destinationVariable, bitWidth, OptionValue::OptionValueType::UINT32});
144+
options.add_options()(name, po::value<std::string>(&(optionValues.back().value)), description);
145+
}
146+
147+
// register 128bit option value
148+
void addOptionValue(boost::program_options::options_description& options, const char *name, const char *description, uint128_t *destinationVariable, unsigned int bitWidth = 128) {
149+
optionValues.push_back({name, "", destinationVariable, bitWidth, OptionValue::OptionValueType::UINT128});
150+
options.add_options()(name, po::value<std::string>(&(optionValues.back().value)), description);
151+
}
152+
153+
// parse option values and assign corresponding variables
154+
void parseOptionValues() {
155+
for(const auto &opt : optionValues) {
156+
if (opt.value.length()) {
157+
uint128_t v;
158+
v = PatternPlayer::getValueFromString(opt.value, opt.bitWidth, opt.name);
159+
if (opt.type == OptionValue::OptionValueType::UINT32) {
160+
*(static_cast<uint32_t *>(opt.destination)) = (uint32_t)v;
161+
} else if (opt.type == OptionValue::OptionValueType::UINT128) {
162+
*(static_cast<uint128_t *>(opt.destination)) = v;
163+
}
164+
}
165+
}
166+
}
142167
};
143168

144169
int main(int argc, char** argv)

src/Cru/Constants.h

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -354,20 +354,29 @@ static constexpr Register CTP_EMU_FBCT(0x00280024);
354354
static constexpr Register CTP_EMU_ORBIT_INIT(0x00280028);
355355

356356
/// Registers for the Pattern Player
357+
/// see https://gitlab.cern.ch/alice-cru/cru-fw/-/tree/pplayer/TTC#address-table
357358
static constexpr Register PATPLAYER_CFG(0x00260000);
358-
static constexpr Register PATPLAYER_IDLE_PATTERN_0(0x00260004);
359-
static constexpr Register PATPLAYER_IDLE_PATTERN_1(0x00260008);
360-
static constexpr Register PATPLAYER_IDLE_PATTERN_2(0x0026000c);
361-
static constexpr Register PATPLAYER_SYNC_PATTERN_0(0x00260010);
362-
static constexpr Register PATPLAYER_SYNC_PATTERN_1(0x00260014);
363-
static constexpr Register PATPLAYER_SYNC_PATTERN_2(0x00260018);
364-
static constexpr Register PATPLAYER_RESET_PATTERN_0(0x0026001c);
365-
static constexpr Register PATPLAYER_RESET_PATTERN_1(0x00260020);
366-
static constexpr Register PATPLAYER_RESET_PATTERN_2(0x00260024);
367-
static constexpr Register PATPLAYER_SYNC_CNT(0x00260028);
368-
static constexpr Register PATPLAYER_DELAY_CNT(0x0026002c);
369-
static constexpr Register PATPLAYER_RESET_CNT(0x00260030);
370-
static constexpr Register PATPLAYER_TRIGGER_SEL(0x00260034);
359+
static constexpr Register PATPLAYER_PAT0_0(0x00260004);
360+
static constexpr Register PATPLAYER_PAT0_1(0x00260008);
361+
static constexpr Register PATPLAYER_PAT0_2(0x0026000c);
362+
static constexpr Register PATPLAYER_PAT1_0(0x00260010);
363+
static constexpr Register PATPLAYER_PAT1_1(0x00260014);
364+
static constexpr Register PATPLAYER_PAT1_2(0x00260018);
365+
static constexpr Register PATPLAYER_PAT2_0(0x0026001c);
366+
static constexpr Register PATPLAYER_PAT2_1(0x00260020);
367+
static constexpr Register PATPLAYER_PAT2_2(0x00260024);
368+
static constexpr Register PATPLAYER_PAT1_LENGTH(0x00260028);
369+
static constexpr Register PATPLAYER_PAT1_DELAY_CNT(0x0026002c);
370+
static constexpr Register PATPLAYER_PAT2_LENGTH(0x00260030);
371+
static constexpr Register PATPLAYER_PAT1_TRIGGER_SEL(0x00260034);
372+
static constexpr Register PATPLAYER_PAT2_TRIGGER_SEL(0x00260038);
373+
static constexpr Register PATPLAYER_PAT3_TRIGGER_SEL(0x0026003c);
374+
static constexpr Register PATPLAYER_PAT2_TRIGGER_TF(0x00260040);
375+
static constexpr Register PATPLAYER_PAT3_LENGTH(0x00260044);
376+
static constexpr Register PATPLAYER_PAT3_0(0x00260048);
377+
static constexpr Register PATPLAYER_PAT3_1(0x0026004c);
378+
static constexpr Register PATPLAYER_PAT3_2(0x00260050);
379+
371380

372381
//** I2C **//
373382
/// I2C base addresses

0 commit comments

Comments
 (0)