|
| 1 | +/// \file ProgramRegisterModify.cxx |
| 2 | +/// \brief Utility that modifies bits of a register on a card |
| 3 | +/// |
| 4 | +/// \author Kostas Alexopoulos ([email protected]) |
| 5 | + |
| 6 | +#include "CommandLineUtilities/Program.h" |
| 7 | +#include "ReadoutCard/ChannelFactory.h" |
| 8 | + |
| 9 | +using namespace AliceO2::roc::CommandLineUtilities; |
| 10 | +namespace po = boost::program_options; |
| 11 | + |
| 12 | +const char* NOREAD_SWITCH("noread"); |
| 13 | + |
| 14 | +class ProgramRegisterModify: public Program |
| 15 | +{ |
| 16 | + public: |
| 17 | + |
| 18 | + virtual Description getDescription() |
| 19 | + { |
| 20 | + return {"Modify Register", "Modify bits of a single register", |
| 21 | + "roc-reg-modify --id=12345 --channel=0 --address=0x8 --position=3 --width=1 --value=0"}; |
| 22 | + } |
| 23 | + |
| 24 | + virtual void addOptions(boost::program_options::options_description& options) |
| 25 | + { |
| 26 | + Options::addOptionRegisterAddress(options); |
| 27 | + Options::addOptionChannel(options); |
| 28 | + Options::addOptionCardId(options); |
| 29 | + Options::addOptionRegisterValue(options); |
| 30 | + options.add_options() |
| 31 | + ("position", |
| 32 | + po::value<int>(&mOptions.position)->default_value(0), |
| 33 | + "Position to modify bits on") |
| 34 | + ("width", |
| 35 | + po::value<int>(&mOptions.width)->default_value(1), |
| 36 | + "Number of bits to modify") |
| 37 | + (NOREAD_SWITCH, |
| 38 | + "No readback of register before and after write"); |
| 39 | + } |
| 40 | + |
| 41 | + virtual void run(const boost::program_options::variables_map& map) |
| 42 | + { |
| 43 | + auto cardId = Options::getOptionCardId(map); |
| 44 | + int address = Options::getOptionRegisterAddress(map); |
| 45 | + int channelNumber = Options::getOptionChannel(map); |
| 46 | + int registerValue = Options::getOptionRegisterValue(map); |
| 47 | + int position = mOptions.position; |
| 48 | + int width = mOptions.width; |
| 49 | + auto readback = !bool(map.count(NOREAD_SWITCH)); |
| 50 | + auto params = AliceO2::roc::Parameters::makeParameters(cardId, channelNumber); |
| 51 | + auto channel = AliceO2::roc::ChannelFactory().getBar(params); |
| 52 | + |
| 53 | + // Registers are indexed by 32 bits (4 bytes) |
| 54 | + if (readback) { |
| 55 | + auto value = channel->readRegister(address/4); |
| 56 | + if (isVerbose()) { |
| 57 | + std::cout << "Before modification:" << std::endl; |
| 58 | + std::cout << Common::makeRegisterString(address, value) << '\n'; |
| 59 | + } else { |
| 60 | + std::cout << "0x" << std::hex << value << '\n'; |
| 61 | + } |
| 62 | + } |
| 63 | + |
| 64 | + channel->modifyRegister(address/4, position, width, registerValue); |
| 65 | + |
| 66 | + if (readback) { |
| 67 | + auto value = channel->readRegister(address/4); |
| 68 | + if (isVerbose()) { |
| 69 | + std::cout << "After modification:" << std::endl; |
| 70 | + std::cout << Common::makeRegisterString(address, value) << '\n'; |
| 71 | + } else { |
| 72 | + std::cout << "0x" << std::hex << value << '\n'; |
| 73 | + } |
| 74 | + } else { |
| 75 | + std::cout << (isVerbose() ? "Done!\n" : "\n"); |
| 76 | + } |
| 77 | + } |
| 78 | + |
| 79 | + struct OptionsStruct |
| 80 | + { |
| 81 | + int position = 0; |
| 82 | + int width = 1; |
| 83 | + }mOptions; |
| 84 | +}; |
| 85 | + |
| 86 | +int main(int argc, char** argv) |
| 87 | +{ |
| 88 | + return ProgramRegisterModify().execute(argc, argv); |
| 89 | +} |
0 commit comments