Skip to content

Commit 2b4961d

Browse files
committed
[flash] Add option to set the CRORC serial
1 parent 7277bbf commit 2b4961d

File tree

8 files changed

+91
-10
lines changed

8 files changed

+91
-10
lines changed

include/ReadoutCard/ParameterTypes/SerialId.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ class SerialId
6565
std::string mSerialIdString;
6666
};
6767

68-
static constexpr int SERIAL_RANGE_LOW(10000);
68+
//TODO: To be updated with sensible values when things are stable.
69+
static constexpr int SERIAL_RANGE_LOW(0);
6970
static constexpr int SERIAL_RANGE_HIGH(100000);
7071

7172
static constexpr int SERIAL_DUMMY(-1);

src/CommandLineUtilities/Options.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static Option<int> channel("channel", "BAR channel number");
6666
static Option<std::string> registerAddress("address", "Register address in hex format");
6767
static Option<int> registerRange("range", "Amount of registers to print past given address");
6868
static Option<std::string> registerValue("value", "Register value, either in decimal or hex (prefix with 0x)");
69-
static Option<std::string> cardId("id", "Card ID: PCI Address or sequence number, as reported by `roc-list-cards`");
69+
static Option<std::string> cardId("id", "Card ID: PCI Address, Serial ID, or sequence number, as reported by `roc-list-cards`");
7070
static Option<std::string> resetLevel("reset", "Reset level [NOTHING, INTERNAL, INTERNAL_DIU, INTERNAL_DIU_SIU]");
7171
} // namespace option
7272

src/CommandLineUtilities/ProgramFlash.cxx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
#include <string>
1919
#include "ReadoutCard/ChannelFactory.h"
2020
#include "Crorc/Crorc.h"
21+
#include "Crorc/CrorcBar.h"
2122
#include "ExceptionInternal.h"
2223

2324
using namespace AliceO2::roc::CommandLineUtilities;
25+
using namespace AliceO2::roc;
2426
using std::cout;
2527
using std::endl;
2628
namespace po = boost::program_options;
@@ -38,7 +40,8 @@ class ProgramCrorcFlash : public Program
3840
virtual void addOptions(po::options_description& options)
3941
{
4042
Options::addOptionCardId(options);
41-
options.add_options()("file", po::value<std::string>(&mFilePath)->required(), "Path of file to flash");
43+
options.add_options()("file", po::value<std::string>(&mFilePath), "Path of firmware file to flash");
44+
options.add_options()("serial", po::value<std::string>(&mSerial), "Serial number to flash");
4245
}
4346

4447
virtual void run(const boost::program_options::variables_map& map)
@@ -54,10 +57,34 @@ class ProgramCrorcFlash : public Program
5457
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Only C-RORC supported for now"));
5558
}
5659

57-
Crorc::programFlash(*(channel.get()), mFilePath, 0, std::cout, &Program::getInterruptFlag());
60+
if (mSerial != "") {
61+
if (mFilePath != "") {
62+
std::cout << "The tool supports either flashing the serial or flashing the firmware;" << std::endl
63+
<< "Both operations not supported in parallel" << std::endl;
64+
return;
65+
}
66+
67+
int serial = std::stoi(mSerial);
68+
if (serial < 0 || serial > 99999) {
69+
std::cerr << "Invalid serial; Legal values: [0-99999]." << std::endl;
70+
return;
71+
}
72+
73+
std::cout << "Setting the serial for the CRORC: " << mSerial << std::endl;
74+
auto crorcBar = std::dynamic_pointer_cast<CrorcBar>(channel);
75+
crorcBar->setSerial(serial);
76+
77+
} else if (mFilePath != "") {
78+
std::cout << "Flashing the CRORC from file: " << mFilePath << std::endl;
79+
Crorc::programFlash(*(channel.get()), mFilePath, 0, std::cout, &Program::getInterruptFlag());
80+
81+
} else {
82+
std::cout << "--file or --serial needs to be provided" << std::endl;
83+
}
5884
}
5985

6086
std::string mFilePath;
87+
std::string mSerial = "";
6188
};
6289
} // Anonymous namespace
6390

src/Crorc/Crorc.cxx

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include "ExceptionInternal.h"
3434
#include "ReadoutCard/RegisterReadWriteInterface.h"
3535

36+
#include <boost/optional/optional_io.hpp>
37+
3638
using namespace std::chrono_literals;
3739
using std::this_thread::sleep_for;
3840
namespace b = boost;
@@ -80,6 +82,8 @@ constexpr int MAX_WAIT = 1000000;
8082
constexpr int REGISTER_DATA_STATUS = Rorc::Flash::IFDSR;
8183
constexpr int REGISTER_ADDRESS = Rorc::Flash::IADR;
8284
constexpr int REGISTER_READY = Rorc::Flash::LRD;
85+
constexpr int DDL_MAX_HW_ID = 64;
86+
constexpr int SN_POS = 33;
8387

8488
// TODO figure out what these are/do
8589
constexpr int MAGIC_VALUE_0 = 0x80;
@@ -168,13 +172,13 @@ void eraseBlock(RegisterReadWriteInterface& bar0, uint32_t address)
168172
}
169173

170174
/// Currently unused, but we'll keep it as "documentation"
171-
/*void writeWord(RegisterReadWriteInterface& bar0, uint32_t address, int value)
175+
void writeWord(RegisterReadWriteInterface& bar0, uint32_t address, int value)
172176
{
173177
writeStatusSleep(bar0, address);
174178
writeStatusSleep(bar0, MAGIC_VALUE_9);
175179
writeStatusSleep(bar0, value);
176180
checkStatus(bar0);
177-
}*/
181+
}
178182

179183
/// Reads a 16-bit flash word and writes it into the given buffer
180184
void readWord(RegisterReadWriteInterface& bar0, uint32_t address, char* data)
@@ -1030,6 +1034,39 @@ boost::optional<int32_t> getSerial(RegisterReadWriteInterface& bar0)
10301034
return { int32_t(serial) };
10311035
}
10321036

1037+
void setSerial(RegisterReadWriteInterface& bar0, int serial)
1038+
{
1039+
1040+
uint32_t address = Rorc::Serial::FLASH_ADDRESS;
1041+
Flash::init(bar0, address);
1042+
Flash::unlockBlock(bar0, address);
1043+
Flash::eraseBlock(bar0, address);
1044+
1045+
// Prepare the data string
1046+
// It needs to be DDL_MAX_HW_ID long and
1047+
// initialized with ' '
1048+
char serialCString[Flash::DDL_MAX_HW_ID + 1];
1049+
serialCString[0] = '\0';
1050+
1051+
for (int i = 0; i < Flash::DDL_MAX_HW_ID - 1; i++) {
1052+
serialCString[i] = ' ';
1053+
}
1054+
1055+
// "S/N: vwxyz" needs to start at SN_POS
1056+
// followed by a ' '
1057+
sprintf(&serialCString[Flash::SN_POS - 5], "S/N: %05d", serial);
1058+
serialCString[Flash::SN_POS + 5] = ' ';
1059+
serialCString[Flash::DDL_MAX_HW_ID - 1] = '\0';
1060+
1061+
// Write the data to the flash
1062+
uint32_t hexValue = 0x0;
1063+
for (int i = 0; i < Flash::DDL_MAX_HW_ID; i += 2, address++) {
1064+
hexValue = Flash::MAGIC_VALUE_13 +
1065+
(serialCString[i] << 8) + serialCString[i + 1];
1066+
Flash::writeWord(bar0, address, hexValue);
1067+
}
1068+
}
1069+
10331070
uint8_t Crorc::ddlReadHw(int destination, int address, long long int time)
10341071
{
10351072
// prepare and send DDL command

src/Crorc/Crorc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ namespace Crorc
3636
/// Note that the BAR must be from channel 0, other channels do not have access to the flash.
3737
boost::optional<int32_t> getSerial(RegisterReadWriteInterface& bar0);
3838

39+
/// Set the serial number on the C-RORC's flash memory.
40+
void setSerial(RegisterReadWriteInterface& bar0, int serial);
41+
3942
/// Program flash using given data file
4043
void programFlash(RegisterReadWriteInterface& bar0, std::string dataFilePath, int addressFlash, std::ostream& out,
4144
const std::atomic<bool>* interrupt = nullptr);

src/Crorc/CrorcBar.cxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,10 @@ int CrorcBar::getEndpointNumber()
6262
return 0;
6363
}
6464

65+
void CrorcBar::setSerial(int serial)
66+
{
67+
Crorc::setSerial(*(mPdaBar.get()), serial);
68+
}
69+
6570
} // namespace roc
6671
} // namespace AliceO2

src/Crorc/CrorcBar.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class CrorcBar final : public BarInterfaceBase
4343
virtual boost::optional<int32_t> getSerial() override;
4444
virtual boost::optional<std::string> getFirmwareInfo() override;
4545
virtual int getEndpointNumber() override;
46+
47+
void setSerial(int serial);
4648
};
4749

4850
} // namespace roc

src/RocPciDevice.cxx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,16 +96,22 @@ void RocPciDevice::initWithSerialId(const SerialId& serialId)
9696
for (const auto& typedPciDevice : Pda::PdaDevice::getPciDevices()) {
9797
PciDevice* pciDevice = typedPciDevice.pciDevice;
9898
DeviceType type;
99+
100+
Utilities::resetSmartPtr(mPdaBar0, pciDevice, 0);
101+
Utilities::resetSmartPtr(mPdaBar2, pciDevice, 2);
102+
103+
int serial;
104+
int endpoint;
99105
if (typedPciDevice.cardType == CardType::Crorc) {
100106
type = DeviceType(deviceTypes.at(0));
107+
serial = type.getSerial(mPdaBar0);
101108
} else {
102109
type = DeviceType(deviceTypes.at(1));
110+
serial = type.getSerial(mPdaBar2);
103111
}
112+
endpoint = type.getEndpoint(mPdaBar0);
104113

105-
Utilities::resetSmartPtr(mPdaBar0, pciDevice, 0);
106-
Utilities::resetSmartPtr(mPdaBar2, pciDevice, 2);
107-
108-
if (type.getSerial(mPdaBar2) == serialId.getSerial() && type.getEndpoint(mPdaBar0) == serialId.getEndpoint()) {
114+
if (serial == serialId.getSerial() && endpoint == serialId.getEndpoint()) {
109115
mPciDevice = pciDevice;
110116
mDescriptor = CardDescriptor{ type.cardType, serialId, type.pciId, addressFromDevice(pciDevice), PciDevice_getNumaNode(pciDevice) };
111117
return;

0 commit comments

Comments
 (0)