@@ -29,10 +29,8 @@ namespace roc {
2929
3030CrorcDmaChannel::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
9191auto 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
174180void 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
238302void 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 }
0 commit comments