Skip to content

Commit 47e5a40

Browse files
authored
Merge pull request #433 from sy-c/orc-518
ORC-518: add ConfigureOptions and o2-roc-config --clock-config
2 parents ae26e5c + cabf463 commit 47e5a40

12 files changed

Lines changed: 139 additions & 23 deletions

File tree

‎README.md‎

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,21 @@ The `CardConfigurator` class offers an interface to configure the Readout Card.
175175
order to configure the CRU or CRORC, one has to create a `CardConfigurator` object. The constructor can either be called with a list of
176176
parameters, or a path to a configuration file, specifying these parameters.
177177

178+
The constructor also takes an optional `ConfigureOptions` struct (see [ConfigureOptions.h](include/ReadoutCard/ConfigureOptions.h)),
179+
which controls *how* the configuration is applied, as opposed to the `Parameters`, which define *what* is configured:
180+
181+
| Field | Values | Default | Description |
182+
| ------------- | ---------------------- | ------- | ------------------------------------------------------------------------------------------------- |
183+
| `force` | `true`, `false` | `false` | Rewrite all settings, even if the card state already matches the requested configuration |
184+
| `clockConfig` | `Yes`, `No`, `Only` | `Yes` | CRU clock (TTC) configuration: run it with the rest, skip it, or run only the clock configuration |
185+
186+
```cpp
187+
ConfigureOptions options;
188+
options.force = true;
189+
options.clockConfig = ConfigureOptions::ClockConfig::No;
190+
CardConfigurator(parameters, options);
191+
```
192+
178193
### CRU Parameters
179194
180195
The `CardConfigurator` utilizes the `Parameters` class, the same class where Parameters are specified for DMA channels. For the
@@ -394,6 +409,20 @@ running instance of readout.exe or roc-bench-dma fail.
394409
### roc-config
395410
Configures the CRU. Can be executed with a list of parameters, or with a [configuration file](#configuration-file). Uses the [Card Configurator](#card-configurator). For more details refer to the `--help` dialog of the binary.
396411
412+
The `--clock-config` option (`yes`, `no`, `only`; default `yes`) sets when the CRU clock is configured. The clock
413+
configuration (clock selection, TTC/PON calibration and GBT calibration) is slow, so it can be done separately from the
414+
rest of the configuration:
415+
* `yes`: the clock is configured together with the other settings.
416+
* `no`: the clock configuration is skipped, and only the other settings are configured.
417+
* `only`: only the clock is configured, and the other settings are left untouched.
418+
419+
When `--force` is not set, only the settings selected by `--clock-config` are compared with the current card state to decide
420+
whether reconfiguring is needed. Example:
421+
```
422+
o2-roc-config --id=b0:00.0 --tf=32 --clock-config=only # configure the clock
423+
o2-roc-config --id=b0:00.0 --tf=32 --clock-config=no # configure the rest, without touching the clock
424+
```
425+
397426
### roc-example
398427
The compiled example of `src/Example.cxx`
399428

‎doc/releaseNotes.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,7 @@ This file describes the main feature changes for released versions of ReadoutCar
103103
## v0.46.2 - 03/03/2026
104104
- boost compatibility
105105
- removed some obsolete CRU BAR code
106+
107+
## next
108+
- o2-roc-config: added option --clock-config=[yes, no, only] to configure the CRU clock separately from the rest, cf [ORC-518](https://its.cern.ch/jira/browse/ORC-518). Default yes (unchanged behavior).
109+
- BarInterface::configure() and CardConfigurator now take a ConfigureOptions struct (force, clockConfig) instead of bool force.

‎include/ReadoutCard/BarInterface.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "ReadoutCard/CardType.h"
2323
#include "ReadoutCard/RegisterReadWriteInterface.h"
2424
#include "ReadoutCard/Parameters.h"
25+
#include "ReadoutCard/ConfigureOptions.h"
2526
#include "boost/optional.hpp"
2627

2728
namespace o2
@@ -76,7 +77,7 @@ class BarInterface : public virtual RegisterReadWriteInterface
7677

7778
virtual int getEndpointNumber() = 0;
7879

79-
virtual void configure(bool force) = 0;
80+
virtual void configure(const ConfigureOptions& options) = 0;
8081
};
8182

8283
} // namespace roc

‎include/ReadoutCard/CardConfigurator.h‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "ReadoutCard/NamespaceAlias.h"
2121
#include "ReadoutCard/CardType.h"
2222
#include "ReadoutCard/Parameters.h"
23+
#include "ReadoutCard/ConfigureOptions.h"
2324

2425
namespace o2
2526
{
@@ -29,8 +30,8 @@ namespace roc
2930
class CardConfigurator
3031
{
3132
public:
32-
CardConfigurator(Parameters::CardIdType cardId, std::string pathToConfigFile, bool forceConfigure = false);
33-
CardConfigurator(Parameters& parameters, bool forceConfigure = false);
33+
CardConfigurator(Parameters::CardIdType cardId, std::string pathToConfigFile, const ConfigureOptions& options = {});
34+
CardConfigurator(Parameters& parameters, const ConfigureOptions& options = {});
3435

3536
private:
3637
void parseConfigUri(CardType::type cardType, std::string configUri, Parameters& parameters);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
/// \file ConfigureOptions.h
12+
/// \brief Definition of the ConfigureOptions struct.
13+
///
14+
/// \author Sylvain Chapeland (sylvain.chapeland@cern.ch)
15+
16+
#ifndef O2_READOUTCARD_INCLUDE_CONFIGUREOPTIONS_H_
17+
#define O2_READOUTCARD_INCLUDE_CONFIGUREOPTIONS_H_
18+
19+
#include "ReadoutCard/NamespaceAlias.h"
20+
21+
namespace o2
22+
{
23+
namespace roc
24+
{
25+
26+
/// Options controlling how a card configuration is applied (not what is configured: see Parameters)
27+
struct ConfigureOptions {
28+
/// Rewrite all settings, even if the card state already matches
29+
bool force = false;
30+
31+
/// Clock (TTC) configuration block: run it, skip it, or run only it
32+
enum class ClockConfig { Yes,
33+
No,
34+
Only };
35+
ClockConfig clockConfig = ClockConfig::Yes;
36+
};
37+
38+
} // namespace roc
39+
} // namespace o2
40+
41+
#endif // O2_READOUTCARD_INCLUDE_CONFIGUREOPTIONS_H_

‎src/CardConfigurator.cxx‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ namespace o2
2626
namespace roc
2727
{
2828

29-
CardConfigurator::CardConfigurator(Parameters::CardIdType cardId, std::string configUri, bool forceConfigure)
29+
CardConfigurator::CardConfigurator(Parameters::CardIdType cardId, std::string configUri, const ConfigureOptions& options)
3030
{
3131
auto cardType = RocPciDevice(cardId).getCardDescriptor().cardType;
3232
Parameters parameters;
@@ -47,23 +47,23 @@ CardConfigurator::CardConfigurator(Parameters::CardIdType cardId, std::string co
4747

4848
auto bar2 = ChannelFactory().getBar(parameters);
4949
try {
50-
bar2->configure(forceConfigure);
50+
bar2->configure(options);
5151
} catch (const Exception& e) {
5252
BOOST_THROW_EXCEPTION(e);
5353
}
5454
}
5555

56-
CardConfigurator::CardConfigurator(Parameters& parameters, bool forceConfigure)
56+
CardConfigurator::CardConfigurator(Parameters& parameters, const ConfigureOptions& options)
5757
{
5858
auto cardType = RocPciDevice(parameters.getCardId().get()).getCardDescriptor().cardType;
5959
try {
6060
if (cardType == CardType::Cru) {
6161
auto bar2 = ChannelFactory().getBar(parameters);
62-
bar2->configure(forceConfigure);
62+
bar2->configure(options);
6363
} else if (cardType == CardType::Crorc) {
6464
parameters.setChannelNumber(0); // we need to change to bar 0
6565
auto bar0 = ChannelFactory().getBar(parameters);
66-
bar0->configure(forceConfigure);
66+
bar0->configure(options);
6767
}
6868
} catch (const Exception& e) {
6969
BOOST_THROW_EXCEPTION(e);

‎src/CommandLineUtilities/ProgramConfig.cxx‎

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@
2222
#include "Crorc/CrorcBar.h"
2323
#include "ReadoutCard/CardConfigurator.h"
2424
#include "ReadoutCard/ChannelFactory.h"
25+
#include "ReadoutCard/ConfigureOptions.h"
2526
#include "ReadoutCard/Exception.h"
2627
#include "ReadoutCard/FirmwareChecker.h"
2728
#include "ReadoutCard/Logger.h"
2829
#include "RocPciDevice.h"
2930
#include <InfoLogger/InfoLogger.hxx>
3031
#include <boost/format.hpp>
32+
#include <boost/algorithm/string/predicate.hpp>
3133

3234
using namespace AliceO2::InfoLogger;
3335
using namespace o2::roc::CommandLineUtilities;
@@ -330,6 +332,9 @@ class ProgramConfig : public Program
330332
options.add_options()("drop-bad-rdh",
331333
po::bool_switch(&mOptions.dropBadRdhEnabled),
332334
"Flag to enable dropping of packets with bad RDH");
335+
options.add_options()("clock-config",
336+
po::value<std::string>(&mOptions.clockConfig)->default_value("yes"),
337+
"Clock (TTC) configuration [yes, no, only]: yes = configure clock with the rest (default), no = skip clock configuration, only = configure only the clock");
333338
options.add_options()("test-mode-ORC501",
334339
po::bool_switch(&o2::roc::testModeORC501),
335340
"Flag to enable test mode as described in JIRA ORC-501");
@@ -430,11 +435,32 @@ class ProgramConfig : public Program
430435

431436
const char* ilFacility = "ReadoutCard/config";
432437

438+
/// Converts the --clock-config option value
439+
static ConfigureOptions::ClockConfig clockConfigFromString(const std::string& value)
440+
{
441+
if (boost::iequals(value, "yes")) {
442+
return ConfigureOptions::ClockConfig::Yes;
443+
} else if (boost::iequals(value, "no")) {
444+
return ConfigureOptions::ClockConfig::No;
445+
} else if (boost::iequals(value, "only")) {
446+
return ConfigureOptions::ClockConfig::Only;
447+
}
448+
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Invalid --clock-config value: " + value + " (expected yes, no or only)"));
449+
}
450+
433451
virtual void run(const boost::program_options::variables_map& map)
434452
{
435453

436454
Logger::setFacility(ilFacility);
437455

456+
// Options controlling how the configuration is applied
457+
ConfigureOptions configureOptions;
458+
configureOptions.force = mOptions.forceConfig;
459+
configureOptions.clockConfig = clockConfigFromString(mOptions.clockConfig);
460+
if (configureOptions.clockConfig != ConfigureOptions::ClockConfig::Yes) {
461+
Logger::get() << "`--clock-config` set to " << mOptions.clockConfig << LogDebugDevel_(4600) << endm;
462+
}
463+
438464
// Configure all cards found - Normally used during boot
439465
if (mOptions.configAll) {
440466
Logger::get() << "Running RoC Configuration for all cards" << LogInfoDevel_(4600) << endm;
@@ -451,7 +477,7 @@ class ProgramConfig : public Program
451477
if (!mOptions.bypassFirmwareCheck) {
452478
try {
453479
FirmwareChecker().checkFirmwareCompatibility(params);
454-
CardConfigurator(card.pciAddress, mOptions.configUri, mOptions.forceConfig);
480+
CardConfigurator(card.pciAddress, mOptions.configUri, configureOptions);
455481
reportStatus(card.pciAddress);
456482
} catch (const std::runtime_error& e) {
457483
Logger::get() << e.what() << LogErrorDevel_(4600) << endm;
@@ -549,7 +575,7 @@ class ProgramConfig : public Program
549575
}
550576

551577
try {
552-
CardConfigurator(params, mOptions.forceConfig);
578+
CardConfigurator(params, configureOptions);
553579
reportStatus(cardId);
554580
} catch (const std::runtime_error& e) {
555581
Logger::get() << e.what() << LogErrorDevel_(4600) << endm;
@@ -565,7 +591,7 @@ class ProgramConfig : public Program
565591
}
566592

567593
try {
568-
CardConfigurator(cardId, mOptions.configUri, mOptions.forceConfig);
594+
CardConfigurator(cardId, mOptions.configUri, configureOptions);
569595
reportStatus(cardId);
570596
} catch (const std::runtime_error& e) {
571597
Logger::get() << e.what() << LogErrorDevel_(4600) << endm;
@@ -580,6 +606,7 @@ class ProgramConfig : public Program
580606

581607
struct OptionsStruct {
582608
std::string clock = "local";
609+
std::string clockConfig = "yes";
583610
std::string configUri = "";
584611
std::string datapathMode = "packet";
585612
std::string downstreamData = "Ctp";

‎src/Crorc/CrorcBar.cxx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ int CrorcBar::getEndpointNumber()
104104
return 0;
105105
}
106106

107-
void CrorcBar::configure(bool /*force*/)
107+
void CrorcBar::configure(const ConfigureOptions& /*options*/)
108108
{
109109
log("Configuring...", LogInfoDevel_(4650));
110110

‎src/Crorc/CrorcBar.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class CrorcBar final : public BarInterfaceBase
5252
boost::optional<int32_t> getSerialNumber();
5353
void setSerial(int serial);
5454

55-
void configure(bool force = false) override;
55+
void configure(const ConfigureOptions& options) override;
5656
Crorc::ReportInfo report(bool forConfig = false);
5757

5858
void resetDevice(bool withSiu);

‎src/Cru/CruBar.cxx‎

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -726,17 +726,21 @@ void CruBar::checkConfigParameters()
726726
}
727727

728728
/// Configures the CRU according to the parameters passed on init
729-
void CruBar::configure(bool force)
729+
void CruBar::configure(const ConfigureOptions& options)
730730
{
731+
bool force = options.force;
732+
bool doClock = options.clockConfig != ConfigureOptions::ClockConfig::No; // run the TTC block
733+
bool onlyClock = options.clockConfig == ConfigureOptions::ClockConfig::Only; // run only the TTC block
734+
731735
// Get current info
732736
Cru::ReportInfo reportInfo = report(true);
733737
populateLinkMap(mLinkMap);
734738

735-
if (static_cast<uint32_t>(mClock) == reportInfo.ttcClock &&
736-
static_cast<uint32_t>(mDownstreamData) == reportInfo.downstreamData &&
737-
std::equal(mLinkMap.begin(), mLinkMap.end(), reportInfo.linkMap.begin()) &&
738-
checkPonUpstreamStatusExpected(reportInfo.ponStatusRegister, reportInfo.onuAddress) &&
739+
bool clockMatches = static_cast<uint32_t>(mClock) == reportInfo.ttcClock &&
739740
//checkClockConsistent(reportInfo.linkMap) &&
741+
checkPonUpstreamStatusExpected(reportInfo.ponStatusRegister, reportInfo.onuAddress);
742+
bool othersMatch = static_cast<uint32_t>(mDownstreamData) == reportInfo.downstreamData &&
743+
std::equal(mLinkMap.begin(), mLinkMap.end(), reportInfo.linkMap.begin()) &&
740744
mCruId == reportInfo.cruId &&
741745
mDynamicOffset == reportInfo.dynamicOffset &&
742746
mTriggerWindowSize == reportInfo.triggerWindowSize &&
@@ -745,8 +749,10 @@ void CruBar::configure(bool force)
745749
mRunStatsEnabled == reportInfo.runStatsEnabled &&
746750
mGbtEnabled == reportInfo.gbtEnabled &&
747751
mTimeFrameLength == reportInfo.timeFrameLength &&
748-
mDropBadRdhEnabled == reportInfo.dropBadRdhEnabled &&
749-
!force) {
752+
mDropBadRdhEnabled == reportInfo.dropBadRdhEnabled;
753+
754+
// only compare the parts selected for configuration
755+
if ((!doClock || clockMatches) && (onlyClock || othersMatch) && !force) {
750756
log("No need to reconfigure further", LogInfoDevel_(4600));
751757
return;
752758
}
@@ -758,7 +764,9 @@ void CruBar::configure(bool force)
758764
DatapathWrapper datapathWrapper = DatapathWrapper(mPdaBar);
759765

760766
/* TTC */
761-
if (static_cast<uint32_t>(mClock) != reportInfo.ttcClock /*|| !checkClockConsistent(reportInfo.linkMap)*/ || force) {
767+
if (!doClock) {
768+
log("Skipping clock configuration", LogInfoDevel_(4601));
769+
} else if (static_cast<uint32_t>(mClock) != reportInfo.ttcClock /*|| !checkClockConsistent(reportInfo.linkMap)*/ || force) {
762770
log("Setting the clock to " + Clock::toString(mClock), LogInfoDevel_(4601));
763771
ttc.setClock(mClock);
764772

@@ -787,6 +795,11 @@ void CruBar::configure(bool force)
787795
}
788796
}
789797

798+
if (onlyClock) {
799+
log("CRU clock configuration done", LogInfoDevel_(4600));
800+
return;
801+
}
802+
790803
if (static_cast<uint32_t>(mDownstreamData) != reportInfo.downstreamData || force) {
791804
log("Setting downstream data: " + DownstreamData::toString(mDownstreamData), LogInfoDevel_(4603));
792805
ttc.selectDownstreamData(mDownstreamData);

0 commit comments

Comments
 (0)