Skip to content

Commit 13b6ba0

Browse files
authored
Improve reset stability
* Separate CRORC reset and arm DDL functions
1 parent 23da358 commit 13b6ba0

File tree

4 files changed

+107
-40
lines changed

4 files changed

+107
-40
lines changed

src/Crorc/Crorc.cxx

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -463,9 +463,10 @@ StWord Crorc::ddlReadDiu(int transid, long long int time)
463463
<< ErrorInfo::StwExpected((b::format("0x00000%x%x%x") % transid % Rorc::IFSTW % destination).str())
464464
<< ErrorInfo::StwReceived((b::format("0x%08lx") % stw.stw).str()));
465465
}
466+
StWord ret = stw;
466467

467468
stw = ddlReadCTSTW(transid, destination, time); // XXX Not sure why we do this...
468-
return stw;
469+
return ret;
469470
}
470471

471472
StWord Crorc::ddlReadCTSTW(int transid, int destination, long long int time){
@@ -623,7 +624,10 @@ void Crorc::ddlResetSiu(int cycle, long long int time)
623624

624625
int transid = 0xf;
625626

626-
for (int i = 0; i < cycle; ++i) {
627+
std::vector<std::string> statusStringsToReturn;
628+
std::vector<std::string> statusStrings;
629+
630+
for (int i = 0; i < cycle; i++) {
627631
try {
628632
sleep_for(10ms);
629633

@@ -632,38 +636,45 @@ void Crorc::ddlResetSiu(int cycle, long long int time)
632636
stword.stw &= Ddl::STMASK;
633637

634638
if (stword.stw & Diu::ERROR_BIT){
635-
// TODO log error
636-
// ddlInterpretIFSTW(retlong, pref, suff, diuConfig.diuVersion);
637-
continue;
639+
statusStrings = ddlInterpretIfstw(stword.stw);
640+
statusStringsToReturn.insert(statusStringsToReturn.end(), statusStrings.begin(), statusStrings.end());
638641
}
639642
else if (mask(stword.stw, Siu::OPTRAN)){
640-
// TODO log error
641-
// ddlInterpretIFSTW(retlong, pref, suff, diuConfig.diuVersion);
642-
continue;
643+
statusStrings = ddlInterpretIfstw(stword.stw);
644+
statusStringsToReturn.insert(statusStringsToReturn.end(), statusStrings.begin(), statusStrings.end());
643645
}
644646

645647
transid = incr15(transid);
646648
stword = ddlReadSiu(transid, time);
647649
stword.stw &= Ddl::STMASK;
648650

649651
if (stword.stw & Diu::ERROR_BIT){
650-
// TODO log error
651-
// ddlInterpretIFSTW(retlong, pref, suff, diuConfig.diuVersion);
652-
continue;
652+
statusStrings = ddlInterpretIfstw(stword.stw);
653+
statusStringsToReturn.insert(statusStringsToReturn.end(), statusStrings.begin(), statusStrings.end());
653654
}
654655

655656
return;
656657
} catch (const Exception& e) {
657658
}
658659
}
659660

660-
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message("Failed to reset SIU"));
661+
// Prepare verbose error message
662+
std::stringstream ss;
663+
ss << "Failed to reset SIU" << std::endl;
664+
for(auto const& string: statusStringsToReturn) {
665+
ss << string << std::endl;
666+
}
667+
BOOST_THROW_EXCEPTION(Exception() << ErrorInfo::Message(ss.str()));
661668
}
662669

663670
/// Sends a reset command
664671
void Crorc::resetCommand(int option, const DiuConfig& diuConfig)
665672
{
666673
uint32_t command = 0;
674+
long long int longret, timeout;
675+
676+
timeout = Ddl::RESPONSE_TIME * diuConfig.pciLoopPerUsec;
677+
667678
if (option & Rorc::Reset::DIU) {
668679
command |= Rorc::CcsrCommand::RESET_DIU;
669680
}
@@ -684,8 +695,9 @@ void Crorc::resetCommand(int option, const DiuConfig& diuConfig)
684695
}
685696
if (option & Rorc::Reset::SIU) {
686697
putCommandRegister(Rorc::DcrCommand::RESET_SIU);
687-
ddlWaitStatus(Ddl::RESPONSE_TIME * diuConfig.pciLoopPerUsec);
688-
ddlReadStatus();
698+
longret = ddlWaitStatus(timeout);
699+
if (longret < timeout)
700+
ddlReadStatus();
689701
}
690702
if (!option || (option & Rorc::Reset::RORC)) {
691703
write(Rorc::RCSR, Rorc::RcsrCommand::RESET_CHAN); //channel reset

src/Crorc/Crorc.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ class Crorc
168168

169169
/// Interprest SIU status
170170
std::vector<std::string> ddlInterpretIfstw(uint32_t ifstw);
171+
172+
StWord ddlReadDiu(int transid, long long int time);
173+
StWord ddlReadSiu(int transid, long long int time);
171174

172175
private:
173176
RegisterReadWriteInterface& bar;
@@ -192,8 +195,6 @@ class Crorc
192195
void ddlSendCommand(int dest, uint32_t command, int transid, uint32_t param, long long int time);
193196
long long int ddlWaitStatus(long long int timeout);
194197
StWord ddlReadStatus();
195-
StWord ddlReadDiu(int transid, long long int time);
196-
StWord ddlReadSiu(int transid, long long int time);
197198
StWord ddlReadCTSTW(int transid, int destination, long long int time);
198199
void emptyDataFifos(int timeoutMicroseconds);
199200
StWord ddlSetSiuLoopBack(const DiuConfig& diuConfig);

src/Crorc/CrorcDmaChannel.cxx

Lines changed: 75 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,8 @@ namespace roc {
2929

3030
CrorcDmaChannel::CrorcDmaChannel(const Parameters& parameters)
3131
: DmaChannelPdaBase(parameters, allowedChannels()), //
32-
//mPdaBar(getRocPciDevice().getPciDevice(), getChannelNumber()), // Initialize main DMA channel BAR
33-
//mPdaBar2(getRocPciDevice().getPciDevice(), 2), // Initialize BAR 2
3432
mPageSize(parameters.getDmaPageSize().get_value_or(DMA_PAGE_SIZE)), // 8 kB default for uniformity with CRU
35-
mInitialResetLevel(ResetLevel::InternalDiuSiu), // It's good to reset at least the card channel in general
33+
mInitialResetLevel(ResetLevel::Internal), // It's good to reset at least the card channel in general
3634
mNoRDYRX(false), // Not sure
3735
mUseFeeAddress(false), // Not sure
3836
mLoopbackMode(parameters.getGeneratorLoopback().get_value_or(LoopbackMode::Internal)), // Internal loopback by default
@@ -86,6 +84,8 @@ CrorcDmaChannel::CrorcDmaChannel(const Parameters& parameters)
8684

8785
getReadyFifoUser()->reset();
8886
mDmaBufferUserspace = getBufferProvider().getAddress();
87+
88+
deviceResetChannel(mInitialResetLevel);
8989
}
9090

9191
auto CrorcDmaChannel::allowedChannels() -> AllowedChannels {
@@ -107,8 +107,14 @@ void CrorcDmaChannel::deviceStartDma()
107107
// Find DIU version, required for armDdl()
108108
mDiuConfig = getCrorc().initDiuVersion();
109109

110-
// Resetting the card,according to the RESET LEVEL parameter
111-
deviceResetChannel(mInitialResetLevel);
110+
// Arming the DDL, according to the channel parameters
111+
if ((mLoopbackMode == LoopbackMode::Siu) || (mLoopbackMode == LoopbackMode::None)) {
112+
armDdl(ResetLevel::InternalDiuSiu);
113+
} else if (mLoopbackMode == LoopbackMode::Diu) {
114+
armDdl(ResetLevel::InternalDiu);
115+
} else {
116+
armDdl(ResetLevel::Internal);
117+
}
112118

113119
// Setting the card to be able to receive data
114120
startDataReceiving();
@@ -172,20 +178,65 @@ void CrorcDmaChannel::deviceStopDma()
172178
}
173179

174180
void CrorcDmaChannel::deviceResetChannel(ResetLevel::type resetLevel)
181+
{
182+
mDiuConfig = getCrorc().initDiuVersion();
183+
uint32_t command;
184+
StWord status;
185+
long long int timeout = Ddl::RESPONSE_TIME * mDiuConfig.pciLoopPerUsec;
186+
187+
if (resetLevel == ResetLevel::Internal) {
188+
log("Resetting CRORC");
189+
log("Clearing Free FIFO");
190+
log("Clearing other FIFOS");
191+
log("Clearing CRORC's byte counters");
192+
command = Rorc::Reset::RORC | Rorc::Reset::FF | Rorc::Reset::FIFOS | Rorc::Reset::ERROR | Rorc::Reset::COUNTERS;
193+
getCrorc().resetCommand(command, mDiuConfig);
194+
} else if (resetLevel == ResetLevel::InternalDiu) {
195+
log("Resetting CRORC & DIU");
196+
command = Rorc::Reset::RORC | Rorc::Reset::DIU;
197+
getCrorc().resetCommand(command, mDiuConfig);
198+
} else if (resetLevel == ResetLevel::InternalDiuSiu) {
199+
log("Resetting SIU...");
200+
log("Switching off CRORC loopback");
201+
getCrorc().setLoopbackOff();
202+
std::this_thread::sleep_for(100ms);
203+
204+
log("Resetting DIU");
205+
getCrorc().resetCommand(Rorc::Reset::DIU, mDiuConfig);
206+
std::this_thread::sleep_for(100ms);
207+
208+
log("Resetting SIU");
209+
getCrorc().resetCommand(Rorc::Reset::SIU, mDiuConfig);
210+
std::this_thread::sleep_for(100ms);
211+
212+
status = getCrorc().ddlReadDiu(0, timeout);
213+
if (((status.stw >> 15) & 0x7) == 0x6) {
214+
BOOST_THROW_EXCEPTION(Exception() <<
215+
ErrorInfo::Message("SIU in no signal state (probably not connected), unable to reset SIU."));
216+
}
217+
218+
status = getCrorc().ddlReadSiu(0, timeout);
219+
/*if (status.stw == -1) { // Comparing unsigned with -1?
220+
BOOST_THROW_EXCEPTION(Exception() <<
221+
ErrorInfo::Message("Error: Timeout - SIU not responding, unable to reset SIU."));
222+
}*/
223+
}
224+
log("Done!");
225+
}
226+
227+
void CrorcDmaChannel::armDdl(ResetLevel::type resetLevel)
175228
{
176229
if (resetLevel == ResetLevel::Nothing) {
177230
return;
178231
}
179232

180233
try {
181-
// Always reset the FreeFifo and the channel
182-
getCrorc().resetCommand(Rorc::Reset::FF, mDiuConfig);
183234
getCrorc().resetCommand(Rorc::Reset::RORC, mDiuConfig);
184235

185-
if (LoopbackMode::isExternal(mLoopbackMode)) {
236+
if (LoopbackMode::isExternal(mLoopbackMode) && (resetLevel != ResetLevel::Internal)) { // At least DIU
186237
getCrorc().armDdl(Rorc::Reset::DIU, mDiuConfig);
187238

188-
if ((resetLevel == ResetLevel::InternalDiuSiu) && (mLoopbackMode != LoopbackMode::Diu))
239+
if ((resetLevel == ResetLevel::InternalDiuSiu) && (mLoopbackMode != LoopbackMode::Diu)) //SIU & NONE
189240
{
190241
// Wait a little before SIU reset.
191242
std::this_thread::sleep_for(100ms); /// XXX Why???
@@ -194,9 +245,22 @@ void CrorcDmaChannel::deviceResetChannel(ResetLevel::type resetLevel)
194245
getCrorc().armDdl(Rorc::Reset::DIU, mDiuConfig);
195246
}
196247

197-
getCrorc().resetCommand(Rorc::Reset::FIFOS & Rorc::Reset::DIU & Rorc::Reset::SIU, mDiuConfig);
198248
getCrorc().armDdl(Rorc::Reset::RORC, mDiuConfig);
249+
std::this_thread::sleep_for(100ms);
250+
251+
if ((resetLevel == ResetLevel::InternalDiuSiu) && (mLoopbackMode != LoopbackMode::Diu)) //SIU & NONE
252+
{
253+
getCrorc().assertLinkUp();
254+
getCrorc().siuCommand(Ddl::RandCIFST);
255+
}
256+
257+
getCrorc().diuCommand(Ddl::RandCIFST);
258+
std::this_thread::sleep_for(100ms);
199259
}
260+
261+
getCrorc().resetCommand(Rorc::Reset::FF, mDiuConfig);
262+
std::this_thread::sleep_for(100ms); /// XXX Give card some time to reset the FreeFIFO
263+
getCrorc().assertFreeFifoEmpty();
200264
}
201265
catch (Exception& e) {
202266
e << ErrorInfo::ResetLevel(resetLevel);
@@ -237,19 +301,6 @@ void CrorcDmaChannel::startDataGenerator()
237301

238302
void CrorcDmaChannel::startDataReceiving()
239303
{
240-
getCrorc().initDiuVersion();
241-
242-
// Preparing the card.
243-
if (LoopbackMode::Siu == mLoopbackMode) {
244-
deviceResetChannel(ResetLevel::InternalDiuSiu);
245-
getCrorc().assertLinkUp();
246-
getCrorc().siuCommand(Ddl::RandCIFST);
247-
getCrorc().diuCommand(Ddl::RandCIFST);
248-
}
249-
250-
getCrorc().resetCommand(Rorc::Reset::FF, mDiuConfig);
251-
std::this_thread::sleep_for(10ms); /// XXX Give card some time to reset the FreeFIFO
252-
getCrorc().assertFreeFifoEmpty();
253304
getCrorc().startDataReceiver(mReadyFifoAddressBus);
254305
}
255306

@@ -289,7 +340,7 @@ void CrorcDmaChannel::pushSuperpage(Superpage superpage)
289340
<< ErrorInfo::Message("Could not push superpage, firmware queue was full (this should never happen)"));
290341
}
291342

292-
for (int i = 0; i < READYFIFO_ENTRIES; i++) { //TODO: *always* push 128 FIFO entries
343+
for (int i = 0; i < READYFIFO_ENTRIES; i++) { // *always* push 128 FIFO entries
293344
auto busAddress = getBusOffsetAddress(superpage.getOffset() + i * mPageSize);
294345
pushFreeFifoPage(i, busAddress);
295346
}

src/Crorc/CrorcDmaChannel.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,9 @@ class CrorcDmaChannel final : public DmaChannelPdaBase
126126
/// Starts pending DMA with given superpage for the initial pages
127127
void startPendingDma();
128128

129+
/// Arms the DDL
130+
void armDdl(ResetLevel::type resetLevel);
131+
129132
/// BAR used for DMA engine and configuration
130133
std::shared_ptr<CrorcBar> crorcBar;
131134

0 commit comments

Comments
 (0)