diff --git a/MAC/APL/PIC/RSP_Driver/src/Cache.cc b/MAC/APL/PIC/RSP_Driver/src/Cache.cc index 93110ccc2efb56b28b59e2faf53147f94ecc2fd0..7b78afc6de0da972939f7638a4ad0b7ba7d57435 100644 --- a/MAC/APL/PIC/RSP_Driver/src/Cache.cc +++ b/MAC/APL/PIC/RSP_Driver/src/Cache.cc @@ -40,6 +40,84 @@ using namespace RSP; using namespace RSP_Protocol; using namespace RTC; +// default settings +// sdo_ss=295:330,331:366,367:402,403:438 +blitz::Array<uint16, 2> str2blitz(const char* str, int max) +{ + string inputstring(str); + char* start = (char*)inputstring.c_str(); + char* end = 0; + bool range = false; + long prevval = 0; + + blitz::Array<uint16, 2> ss(4,36); // ss = subband select + int bank_nr = 0; + int sb_nr = 0; + long i; + + ss = 0; + while (start) { + long val = strtol(start, &end, 10); // read decimal numbers + start = (end ? (*end ? end + 1 : 0) : 0); // advance + if (val >= max || val < 0) { + LOG_WARN(formatString("Error: value %ld out of range",val)); + ss = 0; + return ss; + } + LOG_INFO_STR("val=" << val << " prevval=" << prevval); + if (end) { + switch (*end) { + case ',': + case 0: { + if (range) { + if (0 == prevval && 0 == val) { + val = max - 1; + } + if (val < prevval) { + LOG_WARN("Error: invalid range specification"); + ss = 0; + return ss; + } + + for (i = prevval; i <= val; i++) { + //LOG_INFO(formatString("add value %ld to ss(%d,%d)", i, bank_nr, sb_nr)); + ss(bank_nr, sb_nr) = (uint16)i; + sb_nr++; + if (sb_nr >= 36) { + bank_nr++; + sb_nr = 0; + } + } + } + else { + ss(bank_nr, sb_nr) = (uint16)val; + sb_nr++; + if (sb_nr >= 36) { + bank_nr++; + sb_nr = 0; + } + } + range=false; + } break; + + case ':': { + range=true; + } break; + + default: { + LOG_WARN(formatString("Error: invalid character %c",*end)); + ss = 0; + return ss; + } break; + } // switch + } // if (end) + prevval = val; + } // while + + return (ss); +} + + /** * Instance pointer for the Cache singleton class. */ @@ -89,30 +167,30 @@ CacheBuffer::CacheBuffer(Cache* cache) : m_cache(cache) LOG_DEBUG_STR("itsSDOModeInfo.size() =" << itsSDOModeInfo().size() * sizeof(EPA_Protocol::RSRSDOMode)); LOG_DEBUG_STR("itsSDOSelection.size() =" << itsSDOSelection.subbands().size() * sizeof(uint16)); LOG_DEBUG_STR("itsSDOBitsPerSample.size() =" << sizeof(itsSDOBitsPerSample)); - + LOG_INFO_STR(formatString("CacheBuffer size = %d bytes", - m_beamletweights().size() - + m_subbandselection.crosslets().size() - + m_subbandselection.beamlets().size() - + m_rcusettings().size() - + m_hbasettings().size() - + m_hbareadings().size() - + m_rsusettings().size() - + m_wgsettings().size() - + m_subbandstats().size() - + m_beamletstats().size() - + m_xcstats().size() - + m_systemstatus.board().size() - + m_versions.bp().size() - + m_versions.ap().size() - + m_tdstatus.board().size() - + m_spustatus.subrack().size() - + m_tbbsettings().size() - + m_bypasssettings().size() - + ETH_DATA_LEN + sizeof(uint16) - + sizeof(itsSdsWriteBuffer) - + sizeof(itsSdsReadBuffer) - + itsLatencys().size() + m_beamletweights().size() + + m_subbandselection.crosslets().size() + + m_subbandselection.beamlets().size() + + m_rcusettings().size() + + m_hbasettings().size() + + m_hbareadings().size() + + m_rsusettings().size() + + m_wgsettings().size() + + m_subbandstats().size() + + m_beamletstats().size() + + m_xcstats().size() + + m_systemstatus.board().size() + + m_versions.bp().size() + + m_versions.ap().size() + + m_tdstatus.board().size() + + m_spustatus.subrack().size() + + m_tbbsettings().size() + + m_bypasssettings().size() + + ETH_DATA_LEN + sizeof(uint16) + + sizeof(itsSdsWriteBuffer) + + sizeof(itsSdsReadBuffer) + + itsLatencys().size() + itsSwappedXY.size() + itsBitModeInfo().size() + sizeof(itsBitsPerSample) @@ -150,204 +228,224 @@ CacheBuffer::~CacheBuffer() void CacheBuffer::reset(void) { - // - // Initialize cache, allocating memory and setting default values - // - struct timeval tv; - tv.tv_sec = 0; tv.tv_usec = 0; - m_timestamp.set(tv); + // + // Initialize cache, allocating memory and setting default values + // + struct timeval tv; + tv.tv_sec = 0; tv.tv_usec = 0; + m_timestamp.set(tv); itsBitsPerSample = MAX_BITS_PER_SAMPLE; itsSDOBitsPerSample = MAX_BITS_PER_SAMPLE; - - m_beamletweights().resize( BeamletWeights::SINGLE_TIMESTEP, - StationSettings::instance()->nrRcus(), - MAX_NR_BM_BANKS, - MEPHeader::N_BEAMLETS); - m_beamletweights() = complex<int16>(25,36); + + m_beamletweights().resize( BeamletWeights::SINGLE_TIMESTEP, + StationSettings::instance()->nrRcus(), + MAX_NR_BM_BANKS, + MEPHeader::N_BEAMLETS); + m_beamletweights() = complex<int16>(25,36); // TODO remove this code!!! - for (int rcu = 0 ; rcu < StationSettings::instance()->nrRcus(); rcu++) { - int16 value=0; - for (int bank = 0; bank < (MAX_BITS_PER_SAMPLE/MIN_BITS_PER_SAMPLE); bank++) { - for (int beamlet = 0; beamlet < MEPHeader::N_BEAMLETS; beamlet++) { - m_beamletweights()(0,rcu,bank,beamlet)=complex<int16>(value++,bank+10); - } - } - } + for (int rcu = 0 ; rcu < StationSettings::instance()->nrRcus(); rcu++) { + int16 value=0; + for (int bank = 0; bank < (MAX_BITS_PER_SAMPLE/MIN_BITS_PER_SAMPLE); bank++) { + for (int beamlet = 0; beamlet < MEPHeader::N_BEAMLETS; beamlet++) { + m_beamletweights()(0,rcu,bank,beamlet)=complex<int16>(value++,bank+10); + } + } + } //TODO - m_subbandselection.crosslets().resize(StationSettings::instance()->nrRcus(), - (MAX_BITS_PER_SAMPLE/MIN_BITS_PER_SAMPLE), - MEPHeader::N_LOCAL_XLETS ); - m_subbandselection.crosslets() = 0; + m_subbandselection.crosslets().resize(StationSettings::instance()->nrRcus(), + (MAX_BITS_PER_SAMPLE/MIN_BITS_PER_SAMPLE), + MEPHeader::N_LOCAL_XLETS ); + m_subbandselection.crosslets() = 0; m_subbandselection.beamlets().resize(StationSettings::instance()->nrRcus(), (MAX_BITS_PER_SAMPLE/MIN_BITS_PER_SAMPLE), MEPHeader::N_BEAMLETS ); - m_subbandselection.beamlets() = 0; - - if (GET_CONFIG("RSPDriver.IDENTITY_WEIGHTS", i)) { - // these weights ensure that the beamlet statistics - // exactly match the subband statistics - m_beamletweights() = complex<int16>(GET_CONFIG("RSPDriver.BF_GAIN", i), 0); - - // - // Set default subband selection starting at RSPDriver.FIRST_SUBBAND - // - int firstSubband = GET_CONFIG("RSPDriver.FIRST_SUBBAND", i); - for (int rcu = 0; rcu < m_subbandselection.beamlets().extent(firstDim); rcu++) { - for (int bank = 0; bank < (MAX_BITS_PER_SAMPLE/MIN_BITS_PER_SAMPLE); bank++) { - for (int lane = 0; lane < MEPHeader::N_SERDES_LANES; lane++) { - int start(lane*(MEPHeader::N_BEAMLETS/MEPHeader::N_SERDES_LANES)); - int stop (start + maxBeamletsPerRSP(itsBitsPerSample)); - if (rcu==0) LOG_DEBUG_STR("start=" << start << ", stop=" << stop); - for (int sb = start; sb < stop; sb++) { - m_subbandselection.beamlets()(rcu, bank, sb) = (rcu%N_POL) + (sb*N_POL) + (firstSubband*2); - } // for sb - } // for lane - } // for bank - } // for rcu - LOG_DEBUG_STR("m_subbandsel(0): " << m_subbandselection.beamlets()(0, Range::all(), Range::all())); - } // if identity_weights - - // initialize RCU settings - m_rcusettings().resize(StationSettings::instance()->nrRcus()); - - RCUSettings::Control rcumode; - rcumode.setMode(RCUSettings::Control::MODE_OFF); - m_rcusettings() = rcumode; - - // initialize HBA settings - m_hbasettings().resize(StationSettings::instance()->nrRcus(), N_HBA_ELEM_PER_TILE); - m_hbasettings() = 0; // initialize to 0 - m_hbareadings().resize(StationSettings::instance()->nrRcus(), N_HBA_ELEM_PER_TILE); - m_hbareadings() = 0; // initialize to 0 - - // RSU settings - m_rsusettings().resize(StationSettings::instance()->nrRspBoards()); - RSUSettings::ResetControl rsumode; - rsumode.setRaw(RSUSettings::ResetControl::CTRL_OFF); - m_rsusettings() = rsumode; - - m_wgsettings().resize(StationSettings::instance()->nrRcus()); - WGSettings::WGRegisterType init; - init.freq = 0; - init.phase = 0; - init.ampl = 0; - init.nof_samples = 0; - init.mode = WGSettings::MODE_OFF; - init.preset = WGSettings::PRESET_SINE; - m_wgsettings() = init; - - m_wgsettings.waveforms().resize(StationSettings::instance()->nrRcus(), MEPHeader::N_WAVE_SAMPLES); - m_wgsettings.waveforms() = 0; - - m_subbandstats().resize(StationSettings::instance()->nrRcus(), MEPHeader::N_SUBBANDS); - m_subbandstats() = 0; - + m_subbandselection.beamlets() = 0; + + if (GET_CONFIG("RSPDriver.IDENTITY_WEIGHTS", i)) { + // these weights ensure that the beamlet statistics + // exactly match the subband statistics + m_beamletweights() = complex<int16>(GET_CONFIG("RSPDriver.BF_GAIN", i), 0); + + // + // Set default subband selection starting at RSPDriver.FIRST_SUBBAND + // + int firstSubband = GET_CONFIG("RSPDriver.FIRST_SUBBAND", i); + for (int rcu = 0; rcu < m_subbandselection.beamlets().extent(firstDim); rcu++) { + for (int bank = 0; bank < (MAX_BITS_PER_SAMPLE/MIN_BITS_PER_SAMPLE); bank++) { + for (int lane = 0; lane < MEPHeader::N_SERDES_LANES; lane++) { + int start(lane*(MEPHeader::N_BEAMLETS/MEPHeader::N_SERDES_LANES)); + int stop (start + maxBeamletsPerRSP(itsBitsPerSample)); + if (rcu==0) LOG_DEBUG_STR("start=" << start << ", stop=" << stop); + for (int sb = start; sb < stop; sb++) { + m_subbandselection.beamlets()(rcu, bank, sb) = (rcu%N_POL) + (sb*N_POL) + (firstSubband*2); + } // for sb + } // for lane + } // for bank + } // for rcu + LOG_DEBUG_STR("m_subbandsel(0): " << m_subbandselection.beamlets()(0, Range::all(), Range::all())); + } // if identity_weights + + // initialize RCU settings + m_rcusettings().resize(StationSettings::instance()->nrRcus()); + + RCUSettings::Control rcumode; + rcumode.setMode(RCUSettings::Control::MODE_OFF); + m_rcusettings() = rcumode; + + // initialize HBA settings + m_hbasettings().resize(StationSettings::instance()->nrRcus(), N_HBA_ELEM_PER_TILE); + m_hbasettings() = 0; // initialize to 0 + m_hbareadings().resize(StationSettings::instance()->nrRcus(), N_HBA_ELEM_PER_TILE); + m_hbareadings() = 0; // initialize to 0 + + // RSU settings + m_rsusettings().resize(StationSettings::instance()->nrRspBoards()); + RSUSettings::ResetControl rsumode; + rsumode.setRaw(RSUSettings::ResetControl::CTRL_OFF); + m_rsusettings() = rsumode; + + m_wgsettings().resize(StationSettings::instance()->nrRcus()); + WGSettings::WGRegisterType init; + init.freq = 0; + init.phase = 0; + init.ampl = 0; + init.nof_samples = 0; + init.mode = WGSettings::MODE_OFF; + init.preset = WGSettings::PRESET_SINE; + m_wgsettings() = init; + + m_wgsettings.waveforms().resize(StationSettings::instance()->nrRcus(), MEPHeader::N_WAVE_SAMPLES); + m_wgsettings.waveforms() = 0; + + m_subbandstats().resize(StationSettings::instance()->nrRcus(), MEPHeader::N_SUBBANDS); + m_subbandstats() = 0; + // Number of cep streams -> in normal mode 4, in splitmode 8. - int maxStreams = 8; - m_beamletstats().resize((maxStreams/MEPHeader::N_SERDES_LANES) * N_POL, - (MAX_BITS_PER_SAMPLE/MIN_BITS_PER_SAMPLE) * MEPHeader::N_BEAMLETS); - m_beamletstats() = 0; - - m_xcstats().resize(N_POL, N_POL, StationSettings::instance()->nrBlps(), StationSettings::instance()->nrBlps()); - m_xcstats() = complex<double>(0,0); - - // BoardStatus - m_systemstatus.board().resize(StationSettings::instance()->nrRspBoards()); - BoardStatus boardinit; - memset(&boardinit, 0, sizeof(BoardStatus)); - m_systemstatus.board() = boardinit; - - EPA_Protocol::RSRVersion versioninit = { { 0 }, 0, 0 }; - m_versions.bp().resize(StationSettings::instance()->nrRspBoards()); - m_versions.bp() = versioninit; - m_versions.ap().resize(StationSettings::instance()->nrBlps()); - m_versions.ap() = versioninit; - - // TDBoardStatus - m_tdstatus.board().resize(StationSettings::instance()->nrRspBoards()); - TDBoardStatus tdstatusinit; - memset(&tdstatusinit, 0, sizeof(TDBoardStatus)); - tdstatusinit.unknown = 1; - m_tdstatus.board() = tdstatusinit; - - // SPUBoardStatus - int nrSubRacks = StationSettings::instance()->maxRspBoards()/NR_RSPBOARDS_PER_SUBRACK; - nrSubRacks += (StationSettings::instance()->maxRspBoards() % NR_RSPBOARDS_PER_SUBRACK == 0) ? 0 : 1; - m_spustatus.subrack().resize(nrSubRacks); - LOG_INFO_STR("Resizing SPU array to " << m_spustatus.subrack().size()); - SPUBoardStatus spustatusinit; - memset(&spustatusinit, 0, sizeof(SPUBoardStatus)); - m_spustatus.subrack() = spustatusinit; - - // TBBSettings - m_tbbsettings().resize(StationSettings::instance()->nrRcus()); - bitset<MEPHeader::N_SUBBANDS> bandsel; - bandsel = 0; - m_tbbsettings() = bandsel; - - // BypassSettings (BP and AP's) - LOG_INFO_STR("Resizing bypass array to: " << StationSettings::instance()->nrBlps()); + int maxStreams = 8; + m_beamletstats().resize((maxStreams/MEPHeader::N_SERDES_LANES) * N_POL, + (MAX_BITS_PER_SAMPLE/MIN_BITS_PER_SAMPLE) * MEPHeader::N_BEAMLETS); + m_beamletstats() = 0; + + m_xcstats().resize(N_POL, N_POL, StationSettings::instance()->nrBlps(), StationSettings::instance()->nrBlps()); + m_xcstats() = complex<double>(0,0); + + // BoardStatus + m_systemstatus.board().resize(StationSettings::instance()->nrRspBoards()); + BoardStatus boardinit; + memset(&boardinit, 0, sizeof(BoardStatus)); + m_systemstatus.board() = boardinit; + + EPA_Protocol::RSRVersion versioninit = { { 0 }, 0, 0 }; + m_versions.bp().resize(StationSettings::instance()->nrRspBoards()); + m_versions.bp() = versioninit; + m_versions.ap().resize(StationSettings::instance()->nrBlps()); + m_versions.ap() = versioninit; + + // TDBoardStatus + m_tdstatus.board().resize(StationSettings::instance()->nrRspBoards()); + TDBoardStatus tdstatusinit; + memset(&tdstatusinit, 0, sizeof(TDBoardStatus)); + tdstatusinit.unknown = 1; + m_tdstatus.board() = tdstatusinit; + + // SPUBoardStatus + int nrSubRacks = StationSettings::instance()->maxRspBoards()/NR_RSPBOARDS_PER_SUBRACK; + nrSubRacks += (StationSettings::instance()->maxRspBoards() % NR_RSPBOARDS_PER_SUBRACK == 0) ? 0 : 1; + m_spustatus.subrack().resize(nrSubRacks); + LOG_INFO_STR("Resizing SPU array to " << m_spustatus.subrack().size()); + SPUBoardStatus spustatusinit; + memset(&spustatusinit, 0, sizeof(SPUBoardStatus)); + m_spustatus.subrack() = spustatusinit; + + // TBBSettings + m_tbbsettings().resize(StationSettings::instance()->nrRcus()); + bitset<MEPHeader::N_SUBBANDS> bandsel; + bandsel = 0; + m_tbbsettings() = bandsel; + + // BypassSettings (BP and AP's) + LOG_INFO_STR("Resizing bypass array to: " << StationSettings::instance()->nrBlps()); m_bypasssettings().resize(StationSettings::instance()->nrBlps()); - BypassSettings::Control control; - m_bypasssettings() = control; - - // clear rawdatablock - itsRawDataBlock.address = 0; - itsRawDataBlock.offset = 0; - itsRawDataBlock.dataLen = 0; - memset(itsRawDataBlock.data, 0, RSP_RAW_BLOCK_SIZE); - - // clear SerdesBuffer - itsSdsWriteBuffer.clear(); - for (int rsp = 0; rsp < MAX_N_RSPBOARDS; rsp++) { - itsSdsReadBuffer[rsp].clear(); - } - - // clear I2C flag - itsI2Cuser = NONE; - - // set Splitter not active - itsSplitterActive = false; - // set CEP port enabled - itsCepEnabled0 = false; - itsCepEnabled1 = false; - - // Latency status - itsLatencys().resize(StationSettings::instance()->nrRspBoards()); - RADLatency radlatencyinit; - memset(&radlatencyinit, 0, sizeof(RADLatency)); - itsLatencys() = radlatencyinit; - itsSwappedXY.reset(); - - // BitMode - itsBitModeInfo().resize(StationSettings::instance()->nrRspBoards()); - RSRBeamMode bitmodeinfo; - bitmodeinfo.bm_select = 0; - bitmodeinfo.bm_max = 0; - itsBitModeInfo() = bitmodeinfo; - - // SDOMode - itsSDOModeInfo().resize(StationSettings::instance()->nrRspBoards()); - RSRSDOMode sdomodeinfo; - sdomodeinfo.bm_select = 0; - sdomodeinfo.bm_max = 0; - itsSDOModeInfo() = sdomodeinfo; - + BypassSettings::Control control; + m_bypasssettings() = control; + for (int blp_nr = 0; blp_nr < StationSettings::instance()->nrBlps(); blp_nr += 4) { + m_bypasssettings()(blp_nr).setSDO(1); + } + + // clear rawdatablock + itsRawDataBlock.address = 0; + itsRawDataBlock.offset = 0; + itsRawDataBlock.dataLen = 0; + memset(itsRawDataBlock.data, 0, RSP_RAW_BLOCK_SIZE); + + // clear SerdesBuffer + itsSdsWriteBuffer.clear(); + for (int rsp = 0; rsp < MAX_N_RSPBOARDS; rsp++) { + itsSdsReadBuffer[rsp].clear(); + } + + // clear I2C flag + itsI2Cuser = NONE; + + // set Splitter not active + itsSplitterActive = false; + // set CEP port enabled + itsCepEnabled0 = false; + itsCepEnabled1 = false; + + // Latency status + itsLatencys().resize(StationSettings::instance()->nrRspBoards()); + RADLatency radlatencyinit; + memset(&radlatencyinit, 0, sizeof(RADLatency)); + itsLatencys() = radlatencyinit; + itsSwappedXY.reset(); + + // BitMode + itsBitModeInfo().resize(StationSettings::instance()->nrRspBoards()); + RSRBeamMode bitmodeinfo; + bitmodeinfo.bm_select = 0; + bitmodeinfo.bm_max = 0; + itsBitModeInfo() = bitmodeinfo; + + // SDO default Mode selection + int sdo_mode = 0; + int bits_per_sample = GET_CONFIG("RSPDriver.SDO_MODE", i); + if (bits_per_sample == 8) { sdo_mode = 1; } + else if (bits_per_sample == 5) { sdo_mode = 2; } + else if (bits_per_sample == 4) { sdo_mode = 3; } + + itsSDOModeInfo().resize(StationSettings::instance()->nrRspBoards()); + RSRSDOMode sdomodeinfo; + sdomodeinfo.bm_select = sdo_mode; + sdomodeinfo.bm_max = 3; + itsSDOModeInfo() = sdomodeinfo; + + // SDO default subband selection itsSDOSelection.subbands().resize(StationSettings::instance()->nrRcus(), (MAX_BITS_PER_SAMPLE/MIN_BITS_PER_SAMPLE), MEPHeader::N_SDO_SUBBANDS); - itsSDOSelection.subbands() = 0; - //TODO: itsSDOSelection() = 0; + char select_str[64]; + blitz::Array<uint16, 2> select(4,36); + strncpy(select_str, GET_CONFIG_STRING("RSPDriver.SDO_SS"), 64); + select = str2blitz(select_str, 512); + for (int rcu = 0; rcu < StationSettings::instance()->nrRcus(); rcu++) { + for (int bank = 0; bank < (MAX_BITS_PER_SAMPLE / MIN_BITS_PER_SAMPLE); bank++) { + itsSDOSelection.subbands()(rcu, bank, Range::all()) = 0; + for (int sb = 0; sb < 36; sb++) { + itsSDOSelection.subbands()(rcu, bank, sb) = (select(bank, sb) * 2) + (rcu % 2); + } // for each subband + } // for each bank + } } -SerdesBuffer& CacheBuffer::getSdsReadBuffer(int rspBoardNr) +SerdesBuffer& CacheBuffer::getSdsReadBuffer(int rspBoardNr) { - ASSERTSTR(rspBoardNr >= 0 && rspBoardNr < MAX_N_RSPBOARDS, - "RSPboard index out of range in getting serdesReadBuffer: " << rspBoardNr); - return (itsSdsReadBuffer[rspBoardNr]); + ASSERTSTR(rspBoardNr >= 0 && rspBoardNr < MAX_N_RSPBOARDS, + "RSPboard index out of range in getting serdesReadBuffer: " << rspBoardNr); + return (itsSdsReadBuffer[rspBoardNr]); } void CacheBuffer::setTimestamp(const RTC::Timestamp& timestamp) @@ -360,70 +458,71 @@ void CacheBuffer::setTimestamp(const RTC::Timestamp& timestamp) // Cache& Cache::getInstance() { - if (!m_instance) { - m_instance = new Cache; - } - return (*m_instance); + if (!m_instance) { + m_instance = new Cache; + } + return (*m_instance); } Cache::Cache() : m_front(0), m_back(0) { - // initialize preset waveforms - WGSettings::initWaveformPresets(); + // initialize preset waveforms + WGSettings::initWaveformPresets(); - m_front = new CacheBuffer(this); ASSERT(m_front); - m_back = new CacheBuffer(this); ASSERT(m_back); + m_front = new CacheBuffer(this); ASSERT(m_front); + m_back = new CacheBuffer(this); ASSERT(m_back); - getState().init(StationSettings::instance()->nrRspBoards(), - StationSettings::instance()->nrBlps(), - StationSettings::instance()->nrRcus()); + getState().init(StationSettings::instance()->nrRspBoards(), + StationSettings::instance()->nrBlps(), + StationSettings::instance()->nrRcus()); - // start by writing the correct clock setting - Sequencer::getInstance().startSequence(Sequencer::SEQ_SETCLOCK); + // start by writing the correct clock setting + Sequencer::getInstance().startSequence(Sequencer::SEQ_STARTUP); } Cache::~Cache() { - if (m_front) delete m_front; - if (m_back) delete m_back; + if (m_front) delete m_front; + if (m_back) delete m_back; } void Cache::reset(void) { - m_front->reset(); - m_back->reset(); + m_front->reset(); + m_back->reset(); } void Cache::swapBuffers() { - if (GET_CONFIG("RSPDriver.XC_FILL", i)) { - // fill xcorr array by copying and taking complex conjugate of values mirrored in the diagonal - Array<complex<double>, 4> xc(m_back->getXCStats()()); - firstIndex i; secondIndex j; thirdIndex k; fourthIndex l; - xc = where(xc(i,j,k,l)==complex<double>(0,0), conj(xc(j,i,l,k)), xc(i,j,k,l)); - } - - CacheBuffer *tmp = m_front; - m_front = m_back; - m_back = tmp; + if (GET_CONFIG("RSPDriver.XC_FILL", i)) { + // fill xcorr array by copying and taking complex conjugate of values mirrored in the diagonal + Array<complex<double>, 4> xc(m_back->getXCStats()()); + firstIndex i; secondIndex j; thirdIndex k; fourthIndex l; + xc = where(xc(i,j,k,l)==complex<double>(0,0), conj(xc(j,i,l,k)), xc(i,j,k,l)); + } + + CacheBuffer *tmp = m_front; + m_front = m_back; + m_back = tmp; } void Cache::resetI2Cuser() { - I2Cuser busUser = NONE; - if ((m_front->getI2Cuser() == HBA) && (!m_allstate.hbaprotocol().isMatchAll(RegisterState::CHECK))) { - busUser = HBA; - } - else if ((m_front->getI2Cuser() == RCU_W) && (!m_allstate.rcuprotocol().isMatchAll(RegisterState::CHECK))) { - busUser = RCU_W; - } - else if ((m_front->getI2Cuser() == RCU_R) && (!m_allstate.rcuread().isMatchAll(RegisterState::CHECK))) { - busUser = RCU_R; - } - m_front->setI2Cuser(busUser); - m_back->setI2Cuser (busUser); - LOG_INFO_STR("new I2Cuser = " << ((busUser == NONE) ? "NONE" : - ((busUser == HBA) ? "HBA" : - ((busUser == RCU_R) ? "RCU_R" : "RCU_W")))); + I2Cuser busUser = NONE; + if ((m_front->getI2Cuser() == HBA) && (!m_allstate.hbaprotocol().isMatchAll(RegisterState::CHECK))) { + busUser = HBA; + } + else if ((m_front->getI2Cuser() == RCU_W) && (!m_allstate.rcuprotocol().isMatchAll(RegisterState::CHECK))) { + busUser = RCU_W; + } + else if ((m_front->getI2Cuser() == RCU_R) && (!m_allstate.rcuread().isMatchAll(RegisterState::CHECK))) { + busUser = RCU_R; + } + m_front->setI2Cuser(busUser); + m_back->setI2Cuser (busUser); + LOG_INFO_STR("new I2Cuser = " << ((busUser == NONE) ? "NONE" : + ((busUser == HBA) ? "HBA" : + ((busUser == RCU_R) ? "RCU_R" : "RCU_W")))); } + diff --git a/MAC/APL/PIC/RSP_Driver/src/Cache.h b/MAC/APL/PIC/RSP_Driver/src/Cache.h index ce164ebedafe82da7eea703606a5ddfc9c075a80..4ae8050d0115ed3c85b88975164e03121830368f 100644 --- a/MAC/APL/PIC/RSP_Driver/src/Cache.h +++ b/MAC/APL/PIC/RSP_Driver/src/Cache.h @@ -181,11 +181,11 @@ public: static Cache& getInstance(); virtual ~Cache(); /*@}*/ - + // Reset cache front and back buffers. void reset(void); void resetI2Cuser(void); - + // Swap the front and back buffers. void swapBuffers(); @@ -199,6 +199,7 @@ public: private: // Direct construction not allowed. Cache(); + // Keep register update state. AllRegisterState m_allstate; // communication status of all register diff --git a/MAC/APL/PIC/RSP_Driver/src/RCUProtocolWrite.cc b/MAC/APL/PIC/RSP_Driver/src/RCUProtocolWrite.cc index 80ec840a07c4b5ad9ac4aebfacbe8bea5f3ce11f..a32c822fbda2f7728d2972242f9b233347d10772 100644 --- a/MAC/APL/PIC/RSP_Driver/src/RCUProtocolWrite.cc +++ b/MAC/APL/PIC/RSP_Driver/src/RCUProtocolWrite.cc @@ -45,41 +45,47 @@ namespace LOFAR { const int RCUProtocolWrite::RESULT_WRITE_SIZE; const int RCUProtocolWrite::RESULT_READ_SIZE; - uint8 RCUProtocolWrite::i2c_protocol_write[] = { - 0x0F, // PROTOCOL_C_SEND_BLOCK - 0x01, // I2C address for RCU - 0x03, // size - 0xAA, // <<< replace with data >>> - 0xAA, // <<< replace with data >>> - 0xAA, // <<< replace with data >>> - 0x10, // PROTOCOL_C_RECEIVE_BLOCK - 0x01, // I2C adress for RCU - 0x03, // requested size - 0x13, // PROTOCOL_C_END + uint8 RCUProtocolWrite::i2c_protocol_write[] = { + 0x12, // PROTOCOL_C_WAIT + 0x00, // <<< replace with data, wait byte 0 >>> + 0x00, // <<< replace with data, wait byte 1 >>> + 0x00, // <<< replace with data, wait byte 2 >>> + 0x00, // <<< replace with data, wait byte 3 >>> + 0x0F, // PROTOCOL_C_SEND_BLOCK + 0x01, // I2C address for RCU + 0x03, // size + 0xAA, // <<< replace with data >>> + 0xAA, // <<< replace with data >>> + 0xAA, // <<< replace with data >>> + 0x10, // PROTOCOL_C_RECEIVE_BLOCK + 0x01, // I2C adress for RCU + 0x03, // requested size + 0x13, // PROTOCOL_C_END }; - uint8 RCUProtocolWrite::i2c_protocol_read[] = { - 0x10, // PROTOCOL_C_RECEIVE_BLOCK - 0x01, // I2C adress for RCU - 0x03, // requested size - 0x13, // PROTOCOL_C_END + uint8 RCUProtocolWrite::i2c_protocol_read[] = { + 0x10, // PROTOCOL_C_RECEIVE_BLOCK + 0x01, // I2C adress for RCU + 0x03, // requested size + 0x13, // PROTOCOL_C_END }; - uint8 RCUProtocolWrite::i2c_result_write[] = { - 0x00, // PROTOCOL_C_SEND_BLOCK OK - 0xAA, // <<< replace with expected data >>> - 0xAA, // <<< replace with expected data >>> - 0xAA, // <<< replace with expected data >>> - 0x00, // PROTOCOL_C_RECEIVE_BLOCK OK - 0x00, // PROTOCOL_C_END OK + uint8 RCUProtocolWrite::i2c_result_write[] = { + 0x00, // PROTOCOL_C_WAIT OK + 0x00, // PROTOCOL_C_SEND_BLOCK OK + 0xAA, // <<< replace with expected data >>> + 0xAA, // <<< replace with expected data >>> + 0xAA, // <<< replace with expected data >>> + 0x00, // PROTOCOL_C_RECEIVE_BLOCK OK + 0x00, // PROTOCOL_C_END OK }; - uint8 RCUProtocolWrite::i2c_result_read[] = { - 0xAA, // <<< replace with expected data >>> - 0xAA, // <<< replace with expected data >>> - 0xAA, // <<< replace with expected data >>> - 0x00, // PROTOCOL_C_RECEIVE_BLOCK OK - 0x00, // PROTOCOL_C_END OK + uint8 RCUProtocolWrite::i2c_result_read[] = { + 0xAA, // <<< replace with expected data >>> + 0xAA, // <<< replace with expected data >>> + 0xAA, // <<< replace with expected data >>> + 0x00, // PROTOCOL_C_RECEIVE_BLOCK OK + 0x00, // PROTOCOL_C_END OK }; }; }; @@ -104,119 +110,142 @@ RCUProtocolWrite::~RCUProtocolWrite() // void RCUProtocolWrite::sendrequest() { - uint8 global_rcu = (getBoardId() * NR_RCUS_PER_RSPBOARD) + (getCurrentIndex() / N_WRITES); - bool writeCmdRequested(true); // assume setting the rcumode - - // should we write the RCU? - if (Cache::getInstance().getState().rcuprotocol().get(global_rcu) != RTC::RegisterState::WRITE) { - Cache::getInstance().getState().rcuprotocol().unmodified(global_rcu); - writeCmdRequested = false; // not setting the rcumode, maybe reading? - } - - // should we read the RCU? - if (Cache::getInstance().getState().rcuread().get(global_rcu) != RTC::RegisterState::WRITE) { - Cache::getInstance().getState().rcuread().unmodified(global_rcu); - if (!writeCmdRequested) { // both commands not needed, then we are finished. - setContinue(true); - return; - } - } - - // We need two writes per RCU, first we write a long i2c stream to the rcu. Second we clear the - // result registers of the i2c. - switch (getCurrentIndex() % N_WRITES) { - case 0: { - // set appropriate header - MEPHeader::FieldsType hdr; - if (0 == global_rcu % N_POL) { - hdr = MEPHeader::RCU_PROTOCOLX_HDR; - } else { - hdr = MEPHeader::RCU_PROTOCOLY_HDR; - } - - if (writeCmdRequested) { - // reverse and copy control bytes into i2c_protocol_write - RCUSettings::Control& rcucontrol = Cache::getInstance().getBack().getRCUSettings()()((global_rcu)); - uint32 control = htonl(rcucontrol.getRaw()); - memcpy(i2c_protocol_write+3, &control, 3); - - EPARcuProtocolEvent rcuprotocol; - rcuprotocol.hdr.set(hdr, 1 << (getCurrentIndex() / (N_POL * N_WRITES)), MEPHeader::WRITE, sizeof(i2c_protocol_write)); - rcuprotocol.protocol.setBuffer(i2c_protocol_write, sizeof(i2c_protocol_write)); - - m_hdr = rcuprotocol.hdr; // remember header to match with ack - getBoardPort().send(rcuprotocol); - break; - } - // user wants to read the RCUs - EPARcuProtocolEvent rcuprotocol; - rcuprotocol.hdr.set(hdr, 1 << (getCurrentIndex() / (N_POL * N_WRITES)), MEPHeader::WRITE, sizeof(i2c_protocol_read)); - rcuprotocol.protocol.setBuffer(i2c_protocol_read, sizeof(i2c_protocol_read)); - - m_hdr = rcuprotocol.hdr; // remember header to match with ack - getBoardPort().send(rcuprotocol); - } - break; - - case 1: { - EPAWriteEvent rcuresultwrite; - // set appropriate header - uint8 regid = 0; - if (0 == (global_rcu % N_POL)) { - regid = MEPHeader::RCU_RESULTX; - } else { - regid = MEPHeader::RCU_RESULTY; - } - - int resultSize = writeCmdRequested ? RESULT_WRITE_SIZE : RESULT_READ_SIZE; - rcuresultwrite.hdr.set(MEPHeader::WRITE, 1 << (getCurrentIndex() / (N_POL * N_WRITES)), - MEPHeader::RCU, regid, resultSize, 0); - uint8 clear[RESULT_WRITE_SIZE]; - memset(clear, 0xAA, RESULT_WRITE_SIZE); // clear result - rcuresultwrite.payload.setBuffer(clear, resultSize); - - m_hdr = rcuresultwrite.hdr; // remember header to match with ack - getBoardPort().send(rcuresultwrite); - } - break; - } + uint8 global_rcu = (getBoardId() * NR_RCUS_PER_RSPBOARD) + (getCurrentIndex() / N_WRITES); + bool writeCmdRequested(true); // assume setting the rcumode + + // should we write the RCU? + if (Cache::getInstance().getState().rcuprotocol().get(global_rcu) != RTC::RegisterState::WRITE) { + Cache::getInstance().getState().rcuprotocol().unmodified(global_rcu); + writeCmdRequested = false; // not setting the rcumode, maybe reading? + } + + // should we read the RCU? + if (Cache::getInstance().getState().rcuread().get(global_rcu) != RTC::RegisterState::WRITE) { + Cache::getInstance().getState().rcuread().unmodified(global_rcu); + if (!writeCmdRequested) { // both commands not needed, then we are finished. + setContinue(true); + return; + } + } + + // We need two writes per RCU, first we write a long i2c stream to the rcu. Second we clear the + // result registers of the i2c. + switch (getCurrentIndex() % N_WRITES) { + case 0: { + // set appropriate header + MEPHeader::FieldsType hdr; + if (0 == global_rcu % N_POL) { + hdr = MEPHeader::RCU_PROTOCOLX_HDR; + } else { + hdr = MEPHeader::RCU_PROTOCOLY_HDR; + } + + if (writeCmdRequested) { + // reverse and copy control bytes into i2c_protocol_write + RCUSettings::Control& rcucontrol = Cache::getInstance().getBack().getRCUSettings()()((global_rcu)); + + // add waits while turning on hbas to reduce power peaks. + // if RCU enable changed or rcumode changed + // if rcumode > 0 + if ((rcucontrol.isModeModified()) && (rcucontrol.getMode() > 0)) { + // wait between two RCUs is set to maximum, so that an international station + // running on 160MHz clock can finisch the job in 1 second. + uint32 delay = 0; // in clock ticks, 2000000 = 8msec on 200MHz, 10msec on 160MHz + // add extra wait for each board only for first rcu + /* + if ((global_rcu % 8) == 0) { + delay = (4000000 * (global_rcu / 2)); // power up one power RCU at a time. + //delay = (2000000 * ((global_rcu % 32) / 2)); // per crate, 3 or 6 power RCUs at a time. + } + else if ((global_rcu % 2) == 0) { + delay = 16000000 * (global_rcu / 2); + }*/ + delay = 4000000 * (global_rcu / 2); + uint32 wait = htonl(delay); + LOG_INFO_STR(formatString("RCU I2C wait rcu %d = %f sec (delay=%04x, wait=%04x)", global_rcu, delay * (1./200e6), delay, wait)); + memcpy(i2c_protocol_write+1, &wait, 4); + } + + uint32 control = htonl(rcucontrol.getRaw()); + memcpy(i2c_protocol_write+8, &control, 3); + + EPARcuProtocolEvent rcuprotocol; + rcuprotocol.hdr.set(hdr, 1 << (getCurrentIndex() / (N_POL * N_WRITES)), MEPHeader::WRITE, sizeof(i2c_protocol_write)); + rcuprotocol.protocol.setBuffer(i2c_protocol_write, sizeof(i2c_protocol_write)); + + m_hdr = rcuprotocol.hdr; // remember header to match with ack + getBoardPort().send(rcuprotocol); + break; + } + // user wants to read the RCUs + EPARcuProtocolEvent rcuprotocol; + rcuprotocol.hdr.set(hdr, 1 << (getCurrentIndex() / (N_POL * N_WRITES)), MEPHeader::WRITE, sizeof(i2c_protocol_read)); + rcuprotocol.protocol.setBuffer(i2c_protocol_read, sizeof(i2c_protocol_read)); + + m_hdr = rcuprotocol.hdr; // remember header to match with ack + getBoardPort().send(rcuprotocol); + } + break; + + case 1: { + EPAWriteEvent rcuresultwrite; + // set appropriate header + uint8 regid = 0; + if (0 == (global_rcu % N_POL)) { + regid = MEPHeader::RCU_RESULTX; + } else { + regid = MEPHeader::RCU_RESULTY; + } + + int resultSize = writeCmdRequested ? RESULT_WRITE_SIZE : RESULT_READ_SIZE; + rcuresultwrite.hdr.set(MEPHeader::WRITE, 1 << (getCurrentIndex() / (N_POL * N_WRITES)), + MEPHeader::RCU, regid, resultSize, 0); + uint8 clear[RESULT_WRITE_SIZE]; + memset(clear, 0xAA, RESULT_WRITE_SIZE); // clear result + rcuresultwrite.payload.setBuffer(clear, resultSize); + + m_hdr = rcuresultwrite.hdr; // remember header to match with ack + getBoardPort().send(rcuresultwrite); + } + break; + } } void RCUProtocolWrite::sendrequest_status() { - // intentionally left empty + // intentionally left empty } GCFEvent::TResult RCUProtocolWrite::handleack(GCFEvent& event, GCFPortInterface& /*port*/) { - if (EPA_WRITEACK != event.signal) { - LOG_WARN("RCUProtocolWrite::handleack:: unexpected ack"); - return GCFEvent::NOT_HANDLED; - } - - uint8 global_rcu = (getBoardId() * NR_RCUS_PER_RSPBOARD) + (getCurrentIndex() / N_WRITES); - - EPAWriteackEvent ack(event); - if (!ack.hdr.isValidAck(m_hdr)) { - LOG_ERROR("RCUProtocolWrite::handleack: invalid ack"); - if (m_hdr.m_fields.payload_length == RESULT_WRITE_SIZE) { - Cache::getInstance().getState().rcuprotocol().write_error(global_rcu); - } - else { - Cache::getInstance().getState().rcuread().write_error(global_rcu); - } - return GCFEvent::NOT_HANDLED; - } - - if ((getCurrentIndex() % N_WRITES) == 1) { - // Mark modification as applied when write of RCU result register has completed - if (m_hdr.m_fields.payload_length == RESULT_WRITE_SIZE) { - Cache::getInstance().getState().rcuprotocol().schedule_wait1read(global_rcu); - } - else { - Cache::getInstance().getState().rcuread().schedule_wait1read(global_rcu); - } - } - - return GCFEvent::HANDLED; + if (EPA_WRITEACK != event.signal) { + LOG_WARN("RCUProtocolWrite::handleack:: unexpected ack"); + return GCFEvent::NOT_HANDLED; + } + + uint8 global_rcu = (getBoardId() * NR_RCUS_PER_RSPBOARD) + (getCurrentIndex() / N_WRITES); + + EPAWriteackEvent ack(event); + if (!ack.hdr.isValidAck(m_hdr)) { + LOG_ERROR("RCUProtocolWrite::handleack: invalid ack"); + if (m_hdr.m_fields.payload_length == RESULT_WRITE_SIZE) { + Cache::getInstance().getState().rcuprotocol().write_error(global_rcu); + } + else { + Cache::getInstance().getState().rcuread().write_error(global_rcu); + } + return GCFEvent::NOT_HANDLED; + } + + if ((getCurrentIndex() % N_WRITES) == 1) { + // Mark modification as applied when write of RCU result register has completed + if (m_hdr.m_fields.payload_length == RESULT_WRITE_SIZE) { + Cache::getInstance().getState().rcuprotocol().schedule_wait1read(global_rcu); + } + else { + Cache::getInstance().getState().rcuread().schedule_wait1read(global_rcu); + } + } + + return GCFEvent::HANDLED; } diff --git a/MAC/APL/PIC/RSP_Driver/src/RCUProtocolWrite.h b/MAC/APL/PIC/RSP_Driver/src/RCUProtocolWrite.h index 3247d0a19d3c4ace492821f2bd611009ebde3b58..fb795a49a0c0772e04223257ff36126a0940eaad 100644 --- a/MAC/APL/PIC/RSP_Driver/src/RCUProtocolWrite.h +++ b/MAC/APL/PIC/RSP_Driver/src/RCUProtocolWrite.h @@ -35,41 +35,41 @@ namespace LOFAR { class RCUProtocolWrite : public SyncAction { public: - // Constructors for a RCUProtocolWrite object. - RCUProtocolWrite(GCFPortInterface& board_port, int board_id); + // Constructors for a RCUProtocolWrite object. + RCUProtocolWrite(GCFPortInterface& board_port, int board_id); - // Destructor for RCUProtocolWrite. - virtual ~RCUProtocolWrite(); + // Destructor for RCUProtocolWrite. + virtual ~RCUProtocolWrite(); - // Send the write message. - virtual void sendrequest(); + // Send the write message. + virtual void sendrequest(); - // Send the read request. - virtual void sendrequest_status(); + // Send the read request. + virtual void sendrequest_status(); - // Handle the read result. - virtual GCFEvent::TResult handleack(GCFEvent& event, GCFPortInterface& port); + // Handle the read result. + virtual GCFEvent::TResult handleack(GCFEvent& event, GCFPortInterface& port); private: - EPA_Protocol::MEPHeader m_hdr; + EPA_Protocol::MEPHeader m_hdr; - friend class RCUResultRead; + friend class RCUResultRead; - static const int PROTOCOL_WRITE_SIZE = 10; - static const int PROTOCOL_READ_SIZE = 4; - static const int RESULT_WRITE_SIZE = 6; - static const int RESULT_READ_SIZE = 5; + static const int PROTOCOL_WRITE_SIZE = 15; + static const int PROTOCOL_READ_SIZE = 4; + static const int RESULT_WRITE_SIZE = 7; + static const int RESULT_READ_SIZE = 5; - // construct i2c sequence - static uint8 i2c_protocol_write[PROTOCOL_WRITE_SIZE]; - static uint8 i2c_protocol_read [PROTOCOL_READ_SIZE]; + // construct i2c sequence + static uint8 i2c_protocol_write[PROTOCOL_WRITE_SIZE]; + static uint8 i2c_protocol_read [PROTOCOL_READ_SIZE]; - // construct expected i2c result - static uint8 i2c_result_write[RESULT_WRITE_SIZE]; - static uint8 i2c_result_read [RESULT_READ_SIZE]; + // construct expected i2c result + static uint8 i2c_result_write[RESULT_WRITE_SIZE]; + static uint8 i2c_result_read [RESULT_READ_SIZE]; }; }; // namespace RSP }; // namespace LOFAR - + #endif /* RCUPROTOCOLWRITE_H_ */ diff --git a/MAC/APL/PIC/RSP_Driver/src/RCUWrite.cc b/MAC/APL/PIC/RSP_Driver/src/RCUWrite.cc index 1cd0c908d152cf9fe47d951f9a9535b3c9b4cb9b..fb41304a74e8bec6778bebcfad80b56aa4bd05ac 100644 --- a/MAC/APL/PIC/RSP_Driver/src/RCUWrite.cc +++ b/MAC/APL/PIC/RSP_Driver/src/RCUWrite.cc @@ -71,7 +71,7 @@ void RCUWrite::sendrequest() rcusettings.hdr.set(MEPHeader::RCU_SETTINGS_HDR, 1 << getCurrentIndex()); // also sets payload_length rcusettings.ap = EPA_Protocol::RCUHandler(); rcusettings.ap.input_delay_x = x.getDelay(); - rcusettings.ap.enable_x = y.getEnable(); + rcusettings.ap.enable_x = x.getEnable(); rcusettings.ap.input_delay_y = y.getDelay(); rcusettings.ap.enable_y = y.getEnable(); @@ -91,7 +91,7 @@ GCFEvent::TResult RCUWrite::handleack(GCFEvent& event, GCFPortInterface& /*port* LOG_WARN("RCUWrite::handleack:: unexpected ack"); return GCFEvent::NOT_HANDLED; } - + EPAWriteackEvent ack(event); uint8 global_blp = (getBoardId() * NR_BLPS_PER_RSPBOARD) + getCurrentIndex(); diff --git a/MAC/APL/PIC/RSP_Driver/src/SDOModeWrite.cc b/MAC/APL/PIC/RSP_Driver/src/SDOModeWrite.cc index 1f6d2e94f1f0c484e28843ca98613c82840d569a..cd40aa4856d7a621e0e7f86eaef5ab07a0c86cc6 100644 --- a/MAC/APL/PIC/RSP_Driver/src/SDOModeWrite.cc +++ b/MAC/APL/PIC/RSP_Driver/src/SDOModeWrite.cc @@ -43,7 +43,7 @@ SDOModeWrite::SDOModeWrite(GCFPortInterface& board_port, int board_id) : SyncAction(board_port, board_id, 1) { memset(&itsHdr, 0, sizeof(MEPHeader)); - doAtInit(); + //doAtInit(); } SDOModeWrite::~SDOModeWrite() diff --git a/MAC/APL/PIC/RSP_Driver/src/SDOWrite.cc b/MAC/APL/PIC/RSP_Driver/src/SDOWrite.cc index c6bb5e07fa0eef47fdb1f73dec88a703a609cc9c..019391353b25f5da77acda33fb26704f29989045 100644 --- a/MAC/APL/PIC/RSP_Driver/src/SDOWrite.cc +++ b/MAC/APL/PIC/RSP_Driver/src/SDOWrite.cc @@ -45,7 +45,7 @@ SDOWrite::SDOWrite(GCFPortInterface& board_port, int board_id) { memset(&m_hdr, 0, sizeof(MEPHeader)); - doAtInit(); + //doAtInit(); } SDOWrite::~SDOWrite() diff --git a/MAC/APL/PIC/RSP_Driver/src/Sequencer.cc b/MAC/APL/PIC/RSP_Driver/src/Sequencer.cc index bc390dfb51e9825e47a307f862e4d026eeac20f0..9e96ffde47adc14ac32abfa5a1e992895cd19778 100644 --- a/MAC/APL/PIC/RSP_Driver/src/Sequencer.cc +++ b/MAC/APL/PIC/RSP_Driver/src/Sequencer.cc @@ -32,56 +32,100 @@ using namespace blitz; namespace LOFAR { - using namespace GCF::TM; - using namespace EPA_Protocol; - using namespace RTC; - namespace RSP { + using namespace GCF::TM; + using namespace EPA_Protocol; + using namespace RTC; + namespace RSP { +#define STARTUP_WAIT 10 +#define TDWRITE_WAIT 1 #define TDREAD_TIMEOUT 3 #define RSUCLEAR_WAIT 5 #define WRITE_TIMEOUT 3 +#define WRITE_ALL_TIMEOUT 5 + /* * Implements the following sequences: + * from idle state: + * - SEQ_STARTUP, starts on sequence disableClock + * - SEQ_SETCLOCK, starts on sequence writeClock + * - SEQ_RSPCLEAR, starts on sequence RSUclear * - * idle_state <------------------------------------\ - * || | - * |\-> RSUpreclear_state | RSUCLEAR_WAIT - * | clearClock_state <--------------------\ | - * | writeClock_state <----------------\ | | - * | readClock_state --> readError --/ | | TDREAD_TIMEOUT - * /-|--->RCUdisable_state --> writeError -----/ | WRITE_TIMEOUT - * | | | (ok) --> ok & finalState -----/ - * | | v - * | \--> RSUclear_state <-------------------\ RSUCLEAR_WAIT - * | setBlocksync_state --> writeError --->+ WRITE_TIMEOUT - * | RADwrite_state --> writeError --->+ WRITE_TIMEOUT - * | PPSsync_state --> writeError --->+ WRITE_TIMEOUT - * | RCUenable_state --> writeError --->+ WRITE_TIMEOUT - * | CDOenable_state --> writeError ----/ WRITE_TIMEOUT - * | --> finalState=True --\ - * \<----------------------------------------------/ + * idle_state <--------------------------------------------, + * | | | | + * | | '-> disableClock_state <-------------------. | STARTUP_WAIT + * | | writePLL_state ---> writeError ----' | WRITE_TIMEOUT + * | '----> writeClock_state <-------------------. | STARTUP_WAIT + * | readClock_state ---> readError -----' | TDREAD_TIMEOUT + * | ,------- ok <------------' | + * '--C----> RSUclear_state <----------------------, | RSUCLEAR_WAIT + * |----> RCUdisable_state -----> writeError -------| | WRITE_TIMEOUT + * | ,----- ok <-----------' '--> ok & finalState---C---' + * | '--> setBlocksync_state --> writeError -------| WRITE_TIMEOUT + * | RADwrite_state --> writeError -------| WRITE_TIMEOUT + * | PPSsync_state --> writeError -------| WRITE_TIMEOUT + * | RCUenable_state --> writeError -------| WRITE_TIMEOUT + * | CDOenable_state --> writeError -------| WRITE_TIMEOUT + * | writeSDO_state --> writeError -------' WRITE_TIMEOUT + * | --> finalState=True --, + * | | + * '------------------------------------------------' * */ +/* + * Implements the following sequences: + * from idle state: + * - SEQ_STARTUP, starts on sequence disableClock + * - SEQ_SETCLOCK, starts on sequence writeClock + * - SEQ_RSPCLEAR, starts on sequence RSUclear + * + * idle_state <--------------------------------------------, + * | | | | + * | | '-> disableClock_state <-------------------. | STARTUP_WAIT + * | | writePLL_state ---> writeError ----' | WRITE_TIMEOUT + * | '----> writeClock_state <-------------------. | STARTUP_WAIT + * | readClock_state ---> readError -----' | TDREAD_TIMEOUT + * | ,------- ok <------------' | + * '--C----> RSUclear_state <----------------------, | RSUCLEAR_WAIT + * |----> RCUdisable_state -----> writeError -------| | WRITE_TIMEOUT + * | ,----- ok <-----------' '--> ok & finalState---C---' + * | '--> setAll_state --> writeError -------| WRITE_TIMEOUT + * | - Blocksync | + * | - RADwrite | + * | - PPSsync | + * | - CDOenable | + * | - SDObitmode | + * | - SDOselect | + * | - SDOenable | + * | RCUenable_state --> writeError -------' WRITE_TIMEOUT + * | --> finalState=True --, + * | | + * '------------------------------------------------' + * + */ + + /** * Instance pointer for the Cache singleton class. */ Sequencer* Sequencer::m_instance = 0; -Sequencer::Sequencer() : - GCFFsm ((State)&Sequencer::idle_state), - itsIdle (true), - itsCurSeq (SEQ_NONE), - itsFinalState(false) +Sequencer::Sequencer() : + GCFFsm ((State)&Sequencer::idle_state), + itsIdle (true), + itsCurSeq (SEQ_NONE), + itsClockRequest (0), + itsFinalState(false) { } Sequencer& Sequencer::getInstance() { - if (!m_instance) { - m_instance = new Sequencer; - } - return *m_instance; + if (!m_instance) { + m_instance = new Sequencer; + } + return *m_instance; } Sequencer::~Sequencer() @@ -89,119 +133,260 @@ Sequencer::~Sequencer() void Sequencer::run(GCFEvent& event, GCFPortInterface& port) { - this->doEvent(event, port); + this->doEvent(event, port); } bool Sequencer::isActive() const { - return (!itsIdle); + return (!itsIdle); } GCFEvent::TResult Sequencer::idle_state(GCFEvent& event, GCFPortInterface& /*port*/) { - switch (event.signal) { - case F_INIT: - break; - - case F_ENTRY: { - LOG_INFO("Entering Sequencer::idle_state"); - itsIdle = true; - } - break; - - case F_TIMER: { - if (GET_CONFIG("RSPDriver.DISABLE_INIT", i) == 0) { - if (itsCurSeq == SEQ_SETCLOCK) { - Cache::getInstance().reset(); - TRAN(Sequencer::RSUpreclear_state); - } else if (itsCurSeq == SEQ_RSPCLEAR) { - TRAN(Sequencer::RSUclear_state); - } - } - } - break; - - case F_EXIT: { - LOG_DEBUG("Leaving Sequencer::idle_state"); - itsIdle = false; - itsFinalState = false; - } - break; - - default: - break; - } - - return (GCFEvent::HANDLED); + switch (event.signal) { + case F_INIT: + break; + + case F_ENTRY: { + LOG_INFO("Entering Sequencer::idle_state"); + itsIdle = true; + } + break; + + case F_TIMER: { + if (GET_CONFIG("RSPDriver.DISABLE_INIT", i) == 0) { + if (itsCurSeq == SEQ_STARTUP) { + LOG_DEBUG(">> Start sequencer *startup*"); + TRAN(Sequencer::disableClock_state); + } + else if (itsCurSeq == SEQ_SETCLOCK) { + LOG_DEBUG(">> Start sequencer *setclock*"); + Cache::getInstance().reset(); + TRAN(Sequencer::clearClock_state); + } + else if (itsCurSeq == SEQ_RSPCLEAR) { + LOG_DEBUG(">> Start sequencer *rspclear*"); + TRAN(Sequencer::RSUclear_state); + } + } + } + break; + + case F_EXIT: { + LOG_DEBUG("Leaving Sequencer::idle_state"); + itsIdle = false; + itsFinalState = false; + } + break; + + default: + break; + } + + return (GCFEvent::HANDLED); } // -// RSUpreclear_state(event, port) +// disableClock_state(event, port) // -GCFEvent::TResult Sequencer::RSUpreclear_state(GCFEvent& event, GCFPortInterface& /*port*/) +// before switching clock, goto 125 MHz (both clocks off) +// this prevents locking of firmware +// +GCFEvent::TResult Sequencer::disableClock_state(GCFEvent& event, GCFPortInterface& /*port*/) { - switch (event.signal) { - case F_ENTRY: { - LOG_INFO("Entering Sequencer::RSUpreclear_state"); - - // Change the register to set the clear flag - RSUSettings::ResetControl rsumode; - rsumode.setClear(true); - for (int rsp = 0; rsp < StationSettings::instance()->nrRspBoards(); rsp++) { - Cache::getInstance().getBack().getRSUSettings()()(rsp) = rsumode; - } - - // signal that the register has changed - Cache::getInstance().getState().rsuclear().reset(); - Cache::getInstance().getState().rsuclear().write(); - itsTimer = 0; - break; - } - - case F_TIMER: - if (itsTimer++ > RSUCLEAR_WAIT && Cache::getInstance().getState().rsuclear().isMatchAll(RegisterState::IDLE)) { - TRAN(Sequencer::clearClock_state); - } - break; - - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::RSUpreclear_state"); - break; - - default: - break; - } - - return (GCFEvent::HANDLED); + switch (event.signal) { + case F_ENTRY: { + LOG_INFO("Entering Sequencer::disableClock_state"); + + // save clock + itsClockRequest = Cache::getInstance().getBack().getClock(); + + // set clock to internal board clock (125MHz) + Cache::getInstance().getBack().getClock() = 125; + Cache::getInstance().getFront().getClock() = 125; + + Cache::getInstance().getState().tdwrite().reset(); + Cache::getInstance().getState().tdwrite().write(); + itsTimer = 0; + break; + } + + case F_TIMER: + if (itsTimer++ > STARTUP_WAIT && Cache::getInstance().getState().tdwrite().isMatchAll(RegisterState::IDLE)) { + TRAN(Sequencer::readDisabledClock_state); + } + break; + + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::disableClock_state"); + break; + + default: + break; + } + + return (GCFEvent::HANDLED); } +// +// readClock_state(event, port) +// +GCFEvent::TResult Sequencer::readDisabledClock_state(GCFEvent& event, GCFPortInterface& /*port*/) +{ + switch (event.signal) { + case F_ENTRY: + LOG_INFO("Entering Sequencer::readDisabledClock_state"); + Cache::getInstance().getState().tdread().reset(); + Cache::getInstance().getState().tdread().read(); + itsTimer = 0; + break; + + case F_TIMER: + if (Cache::getInstance().getState().tdread().getMatchCount(RegisterState::READ_ERROR) > 0) { + if (itsTimer++ > TDREAD_TIMEOUT) { + LOG_WARN("Failed to verify setting of clock. Retrying..."); + TRAN(Sequencer::disableClock_state); + } else { + // read again + Cache::getInstance().getState().tdread().reset(); + Cache::getInstance().getState().tdread().read(); + } + } + else if (Cache::getInstance().getState().tdread().isMatchAll(RegisterState::IDLE)) { + LOG_DEBUG_STR(formatString("disabled clock freq = %d MHz", Cache::getInstance().getBack().getClock())); + if (Cache::getInstance().getBack().getClock() == 125) { + TRAN(Sequencer::writePLL_state); + } + else { + TRAN(Sequencer::disableClock_state); + } + } + break; + + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::readDisabledClock_state"); + break; + + default: + break; + } + + return (GCFEvent::HANDLED); +} + + +// +// writePLL_state(event, port) +// +GCFEvent::TResult Sequencer::writePLL_state(GCFEvent& event, GCFPortInterface& /*port*/) +{ + switch (event.signal) { + case F_ENTRY: { + LOG_INFO("Entering Sequencer::writePLL_state"); + + // setting clock to 0, will result in programming the PLL + Cache::getInstance().getBack().getClock() = 0; + Cache::getInstance().getFront().getClock() = 0; + + // signal that the register has changed + Cache::getInstance().getState().tdwrite().reset(); + Cache::getInstance().getState().tdwrite().write(); + itsTimer = 0; + break; + } + + case F_TIMER: + if (itsTimer++ > TDWRITE_WAIT && Cache::getInstance().getState().tdwrite().isMatchAll(RegisterState::IDLE)) { + TRAN(Sequencer::readPLL_state); + } + break; + + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::writePLL_state"); + break; + + default: + break; + } + + return (GCFEvent::HANDLED); +} + +// +// readPLL_state(event, port) +// +GCFEvent::TResult Sequencer::readPLL_state(GCFEvent& event, GCFPortInterface& /*port*/) +{ + switch (event.signal) { + case F_ENTRY: { + LOG_INFO("Entering Sequencer::readPLL_state"); + + //TODO: + + // signal that the register has changed + Cache::getInstance().getState().tdread().reset(); + Cache::getInstance().getState().tdread().read(); + itsTimer = 0; + break; + } + + case F_TIMER: + if (Cache::getInstance().getState().tdread().getMatchCount(RegisterState::READ_ERROR) > 0) { + if (itsTimer++ > TDREAD_TIMEOUT) { + LOG_WARN("Failed to verify setting of pll. Retrying..."); + TRAN(Sequencer::writePLL_state); + } else { + // read again + Cache::getInstance().getState().tdread().reset(); + Cache::getInstance().getState().tdread().read(); + } + } + else if (Cache::getInstance().getState().tdread().isMatchAll(RegisterState::IDLE)) { + Cache::getInstance().getBack().getClock() = 200; //itsClockRequest; + Cache::getInstance().getFront().getClock() = 200; //itsClockRequest; + TRAN(Sequencer::writeClock_state); + } + break; + + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::readPLL_state"); + break; + + default: + break; + } + + return (GCFEvent::HANDLED); +} + + // // clearClock_state(event, port) // GCFEvent::TResult Sequencer::clearClock_state(GCFEvent& event, GCFPortInterface& /*port*/) { - switch (event.signal) { - case F_ENTRY: - LOG_INFO("Entering Sequencer::clearClock_state"); - Cache::getInstance().getState().tdclear().reset(); - Cache::getInstance().getState().tdclear().write(); - break; - - case F_TIMER: - if (Cache::getInstance().getState().tdclear().isMatchAll(RegisterState::IDLE)) { - TRAN(Sequencer::writeClock_state); - } - break; - - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::clearClock_state"); - break; - - default: - break; - } - - return (GCFEvent::HANDLED); + switch (event.signal) { + case F_ENTRY: + LOG_INFO("Entering Sequencer::clearClock_state"); + Cache::getInstance().getState().tdclear().reset(); + Cache::getInstance().getState().tdclear().write(); + break; + + case F_TIMER: + if (Cache::getInstance().getState().tdclear().isMatchAll(RegisterState::IDLE)) { + TRAN(Sequencer::writeClock_state); + } + break; + + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::clearClock_state"); + break; + + default: + break; + } + + return (GCFEvent::HANDLED); } // @@ -209,28 +394,29 @@ GCFEvent::TResult Sequencer::clearClock_state(GCFEvent& event, GCFPortInterface& // GCFEvent::TResult Sequencer::writeClock_state(GCFEvent& event, GCFPortInterface& /*port*/) { - switch (event.signal) { - case F_ENTRY: - LOG_INFO("Entering Sequencer::writeClock_state"); - Cache::getInstance().getState().tdwrite().reset(); - Cache::getInstance().getState().tdwrite().write(); - break; - - case F_TIMER: - if (Cache::getInstance().getState().tdwrite().isMatchAll(RegisterState::IDLE)) { - TRAN(Sequencer::readClock_state); - } - break; - - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::writeClock_state"); - break; - - default: - break; - } - - return (GCFEvent::HANDLED); + switch (event.signal) { + case F_ENTRY: + LOG_INFO("Entering Sequencer::writeClock_state"); + Cache::getInstance().getState().tdwrite().reset(); + Cache::getInstance().getState().tdwrite().write(); + itsTimer = 0; + break; + + case F_TIMER: + if (itsTimer++ > STARTUP_WAIT && Cache::getInstance().getState().tdwrite().isMatchAll(RegisterState::IDLE)) { + TRAN(Sequencer::readClock_state); + } + break; + + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::writeClock_state"); + break; + + default: + break; + } + + return (GCFEvent::HANDLED); } // @@ -238,38 +424,39 @@ GCFEvent::TResult Sequencer::writeClock_state(GCFEvent& event, GCFPortInterface& // GCFEvent::TResult Sequencer::readClock_state(GCFEvent& event, GCFPortInterface& /*port*/) { - switch (event.signal) { - case F_ENTRY: - LOG_INFO("Entering Sequencer::readClock_state"); - Cache::getInstance().getState().tdread().reset(); - Cache::getInstance().getState().tdread().read(); - itsTimer = 0; - break; - - case F_TIMER: - if (Cache::getInstance().getState().tdread().getMatchCount(RegisterState::READ_ERROR) > 0) { - if (itsTimer++ > TDREAD_TIMEOUT) { - LOG_WARN("Failed to verify setting of clock. Retrying..."); - TRAN(Sequencer::writeClock_state); - } else { - // read again - Cache::getInstance().getState().tdread().reset(); - Cache::getInstance().getState().tdread().read(); - } - } else if (Cache::getInstance().getState().tdread().isMatchAll(RegisterState::IDLE)) { - TRAN(Sequencer::RCUdisable_state); - } - break; - - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::readClock_state"); - break; - - default: - break; - } - - return (GCFEvent::HANDLED); + switch (event.signal) { + case F_ENTRY: + LOG_INFO("Entering Sequencer::readClock_state"); + Cache::getInstance().getState().tdread().reset(); + Cache::getInstance().getState().tdread().read(); + itsTimer = 0; + break; + + case F_TIMER: + if (Cache::getInstance().getState().tdread().getMatchCount(RegisterState::READ_ERROR) > 0) { + if (itsTimer++ > TDREAD_TIMEOUT) { + LOG_WARN("Failed to verify setting of clock. Retrying..."); + TRAN(Sequencer::writeClock_state); + } else { + // read again + Cache::getInstance().getState().tdread().reset(); + Cache::getInstance().getState().tdread().read(); + } + } + else if (Cache::getInstance().getState().tdread().isMatchAll(RegisterState::IDLE)) { + TRAN(Sequencer::RCUdisable_state); + } + break; + + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::readClock_state"); + break; + + default: + break; + } + + return (GCFEvent::HANDLED); } // @@ -277,39 +464,40 @@ GCFEvent::TResult Sequencer::readClock_state(GCFEvent& event, GCFPortInterface& // GCFEvent::TResult Sequencer::RCUdisable_state(GCFEvent& event, GCFPortInterface& /*port*/) { - switch (event.signal) { - case F_ENTRY: - LOG_INFO("Entering Sequencer::RCUdisable_state"); - enableRCUs(false); - itsTimer = 0; - break; - - case F_TIMER: - if (itsTimer++ > WRITE_TIMEOUT && - Cache::getInstance().getState().rcusettings().getMatchCount(RegisterState::WRITE) > 0) { - LOG_WARN("Failed to disable receivers. Retrying..."); - itsFinalState = false; - TRAN(Sequencer::clearClock_state); - } else if (Cache::getInstance().getState().rcusettings().isMatchAll(RegisterState::IDLE)) { - if (itsFinalState) { - stopSequence(); - TRAN(Sequencer::idle_state); - } - else { - TRAN(Sequencer::RSUclear_state); - } - } - break; - - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::RCUdisable_state"); - break; - - default: - break; - } - - return (GCFEvent::HANDLED); + switch (event.signal) { + case F_ENTRY: + LOG_INFO("Entering Sequencer::RCUdisable_state"); + enableRCUs(false); + itsTimer = 0; + break; + + case F_TIMER: + if (itsTimer++ > WRITE_TIMEOUT && Cache::getInstance().getState().rcusettings().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to disable receivers. Retrying..."); + itsFinalState = false; + TRAN(Sequencer::clearClock_state); + } else if (Cache::getInstance().getState().rcusettings().isMatchAll(RegisterState::IDLE)) { + if (itsFinalState) { + stopSequence(); + LOG_DEBUG("<< Stop sequencer"); + TRAN(Sequencer::idle_state); + } + else { + //TRAN(Sequencer::setBlocksync_state); + TRAN(Sequencer::setAll_state); + } + } + break; + + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::RCUdisable_state"); + break; + + default: + break; + } + + return (GCFEvent::HANDLED); } // @@ -317,75 +505,173 @@ GCFEvent::TResult Sequencer::RCUdisable_state(GCFEvent& event, GCFPortInterface& // GCFEvent::TResult Sequencer::RSUclear_state(GCFEvent& event, GCFPortInterface& /*port*/) { - switch (event.signal) { - case F_ENTRY: { - LOG_INFO("Entering Sequencer::RSUclear_state"); - - // Change the register to set the clear flag - RSUSettings::ResetControl rsumode; - rsumode.setClear(true); - for (int rsp = 0; rsp < StationSettings::instance()->nrRspBoards(); rsp++) { - Cache::getInstance().getBack().getRSUSettings()()(rsp) = rsumode; - } - - // signal that the register has changed - Cache::getInstance().getState().rsuclear().reset(); - Cache::getInstance().getState().rsuclear().write(); - - itsTimer = 0; - break; - } - - case F_TIMER: - if (itsTimer++ > RSUCLEAR_WAIT && Cache::getInstance().getState().rsuclear().isMatchAll(RegisterState::IDLE)) { - TRAN(Sequencer::setBlocksync_state); - } - break; - - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::RSUclear_state"); - break; - - default: - break; - } - - return (GCFEvent::HANDLED); + switch (event.signal) { + case F_ENTRY: { + LOG_INFO("Entering Sequencer::RSUclear_state"); + + // Change the register to set the clear flag + RSUSettings::ResetControl rsumode; + rsumode.setClear(true); + for (int rsp = 0; rsp < StationSettings::instance()->nrRspBoards(); rsp++) { + Cache::getInstance().getBack().getRSUSettings()()(rsp) = rsumode; + } + + // signal that the register has changed + Cache::getInstance().getState().rsuclear().reset(); + Cache::getInstance().getState().rsuclear().write(); + + itsTimer = 0; + break; + } + + case F_TIMER: + if (itsTimer++ > RSUCLEAR_WAIT && Cache::getInstance().getState().rsuclear().isMatchAll(RegisterState::IDLE)) { + //TRAN(Sequencer::setBlocksync_state); + TRAN(Sequencer::setAll_state); + } + break; + + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::RSUclear_state"); + break; + + default: + break; + } + + return (GCFEvent::HANDLED); +} + +// +// setAll_state(event, port) +// +GCFEvent::TResult Sequencer::setAll_state(GCFEvent& event, GCFPortInterface& /*port*/) +{ + switch (event.signal) { + case F_ENTRY: + LOG_INFO("Entering Sequencer::setAll_state"); + Cache::getInstance().getState().bs().reset(); + Cache::getInstance().getState().bs().write(); + Cache::getInstance().getState().rad().reset(); + Cache::getInstance().getState().rad().write(); + Cache::getInstance().getState().crcontrol().reset(); + Cache::getInstance().getState().crcontrol().read(); + Cache::getInstance().getState().cdo().reset(); + Cache::getInstance().getState().cdo().write(); + if (StationSettings::instance()->hasAartfaac()) { + Cache::getInstance().getState().sdoState().reset(); + Cache::getInstance().getState().sdoState().write(); + Cache::getInstance().getState().sdoSelectState().reset(); + Cache::getInstance().getState().sdoSelectState().write(); + + for (int blp_nr = 0; blp_nr < StationSettings::instance()->nrBlps(); blp_nr += 4) { + Cache::getInstance().getState().bypasssettings().reset(blp_nr); + Cache::getInstance().getState().bypasssettings().write(blp_nr); + } + } + itsTimer = 0; + break; + + case F_TIMER: + if (itsTimer++ > WRITE_ALL_TIMEOUT) { + if (Cache::getInstance().getState().bs().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to set BS (blocksync) register. Retrying..."); + Cache::getInstance().getState().bs().reset(); + } + if (Cache::getInstance().getState().rad().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to write RAD settings register. Retrying..."); + } + if (Cache::getInstance().getState().crcontrol().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to write PPSsync settings register. Retrying..."); + stringstream ss; + Cache::getInstance().getState().crcontrol().print(ss); + LOG_DEBUG_STR("PPSsync failure state: " << ss); + } + if (Cache::getInstance().getState().cdo().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to enable receivers. Retrying..."); + } +/* + if (StationSettings::instance()->hasAartfaac()) { + if (Cache::getInstance().getState().sdoState().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to set SDO state. Retrying..."); + } + if (Cache::getInstance().getState().sdoSelectState().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to set SDO select. Retrying..."); + } + if (Cache::getInstance().getState().bypasssettings().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to set SDO settings. Retrying..."); + } + } +*/ + TRAN(Sequencer::RSUclear_state); + } + else if (Cache::getInstance().getState().bs().isMatchAll(RegisterState::IDLE) + && Cache::getInstance().getState().rad().isMatchAll(RegisterState::IDLE) + && Cache::getInstance().getState().crcontrol().isMatchAll(RegisterState::IDLE) + && Cache::getInstance().getState().cdo().isMatchAll(RegisterState::IDLE) ) { + + TRAN(Sequencer::RCUenable_state); +/* + if (StationSettings::instance()->hasAartfaac()) { + if ( Cache::getInstance().getState().sdoState().isMatchAll(RegisterState::IDLE) + && Cache::getInstance().getState().sdoSelectState().isMatchAll(RegisterState::IDLE) + && Cache::getInstance().getState().bypasssettings().isMatchAll(RegisterState::IDLE) ) { + TRAN(Sequencer::RCUenable_state); + } + } + else { + TRAN(Sequencer::RCUenable_state); + } +*/ + } + break; + + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::setAll_state"); + break; + + default: + break; + } + + return (GCFEvent::HANDLED); } + // // setBlocksync_state(event, port) // GCFEvent::TResult Sequencer::setBlocksync_state(GCFEvent& event, GCFPortInterface& /*port*/) { - switch (event.signal) { - case F_ENTRY: - LOG_INFO("Entering Sequencer::setBlocksync_state"); - Cache::getInstance().getState().bs().reset(); - Cache::getInstance().getState().bs().write(); - itsTimer = 0; - break; - - case F_TIMER: - if (itsTimer++ > WRITE_TIMEOUT && - Cache::getInstance().getState().bs().getMatchCount(RegisterState::WRITE) > 0) { - LOG_WARN("Failed to set BS (blocksync) register. Retrying..."); - Cache::getInstance().getState().bs().reset(); - TRAN(Sequencer::RSUclear_state); - } else if (Cache::getInstance().getState().bs().isMatchAll(RegisterState::IDLE)) { - TRAN(Sequencer::RADwrite_state); - } - break; - - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::setBlocksync_state"); - break; - - default: - break; - } - - return (GCFEvent::HANDLED); + switch (event.signal) { + case F_ENTRY: + LOG_INFO("Entering Sequencer::setBlocksync_state"); + Cache::getInstance().getState().bs().reset(); + Cache::getInstance().getState().bs().write(); + itsTimer = 0; + break; + + case F_TIMER: + if (itsTimer++ > WRITE_TIMEOUT && + Cache::getInstance().getState().bs().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to set BS (blocksync) register. Retrying..."); + Cache::getInstance().getState().bs().reset(); + TRAN(Sequencer::RSUclear_state); + } + else if (Cache::getInstance().getState().bs().isMatchAll(RegisterState::IDLE)) { + TRAN(Sequencer::RADwrite_state); + } + break; + + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::setBlocksync_state"); + break; + + default: + break; + } + + return (GCFEvent::HANDLED); } // @@ -393,33 +679,34 @@ GCFEvent::TResult Sequencer::setBlocksync_state(GCFEvent& event, GCFPortInterfac // GCFEvent::TResult Sequencer::RADwrite_state(GCFEvent& event, GCFPortInterface& /*port*/) { - switch (event.signal) { - case F_ENTRY: - LOG_INFO("Entering Sequencer::RADwrit_state"); - Cache::getInstance().getState().rad().reset(); - Cache::getInstance().getState().rad().write(); - itsTimer = 0; - break; - - case F_TIMER: - if (itsTimer++ > WRITE_TIMEOUT && - Cache::getInstance().getState().rad().getMatchCount(RegisterState::WRITE) > 0) { - LOG_WARN("Failed to write RAD settings register. Retrying..."); - TRAN(Sequencer::RSUclear_state); - } else if (Cache::getInstance().getState().rad().isMatchAll(RegisterState::IDLE)) { - TRAN(Sequencer::PPSsync_state); - } - break; - - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::RADwrite_state"); - break; - - default: - break; - } - - return (GCFEvent::HANDLED); + switch (event.signal) { + case F_ENTRY: + LOG_INFO("Entering Sequencer::RADwrite_state"); + Cache::getInstance().getState().rad().reset(); + Cache::getInstance().getState().rad().write(); + itsTimer = 0; + break; + + case F_TIMER: + if (itsTimer++ > WRITE_TIMEOUT && + Cache::getInstance().getState().rad().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to write RAD settings register. Retrying..."); + TRAN(Sequencer::RSUclear_state); + } + else if (Cache::getInstance().getState().rad().isMatchAll(RegisterState::IDLE)) { + TRAN(Sequencer::PPSsync_state); + } + break; + + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::RADwrite_state"); + break; + + default: + break; + } + + return (GCFEvent::HANDLED); } // @@ -427,374 +714,196 @@ GCFEvent::TResult Sequencer::RADwrite_state(GCFEvent& event, GCFPortInterface& / // GCFEvent::TResult Sequencer::PPSsync_state(GCFEvent& event, GCFPortInterface& /*port*/) { - switch (event.signal) { - case F_ENTRY: - LOG_INFO("Entering Sequencer::PPSsync_state"); - Cache::getInstance().getState().crcontrol().reset(); // set to IDLE - Cache::getInstance().getState().crcontrol().read(); // set to READ - // Note: we set the state to read iso write so that the CRSync action knows it a new start. - // It will send a 'reset' to the registers first and than change the state to write during - // the repeated writes till all APs have the right delay. - itsTimer = 0; - break; - - case F_TIMER: - if (itsTimer++ > WRITE_TIMEOUT && - Cache::getInstance().getState().crcontrol().getMatchCount(RegisterState::WRITE) > 0) { - LOG_WARN("Failed to write PPSsync settings register. Retrying..."); - stringstream ss; - Cache::getInstance().getState().crcontrol().print(ss); - LOG_DEBUG_STR("PPSsync failure state: " << ss); - TRAN(Sequencer::RSUclear_state); - } else if (Cache::getInstance().getState().crcontrol().isMatchAll(RegisterState::IDLE)) { - TRAN(Sequencer::RCUenable_state); - } - break; - - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::PPSsync_state"); - break; - - default: - break; - } - - return (GCFEvent::HANDLED); -} + switch (event.signal) { + case F_ENTRY: + LOG_INFO("Entering Sequencer::PPSsync_state"); + Cache::getInstance().getState().crcontrol().reset(); // set to IDLE + Cache::getInstance().getState().crcontrol().read(); // set to READ + // Note: we set the state to read iso write so that the CRSync action knows it a new start. + // It will send a 'reset' to the registers first and than change the state to write during + // the repeated writes till all APs have the right delay. + itsTimer = 0; + break; -// -// enableRCUs [private] -// -void Sequencer::enableRCUs(bool on) -{ - RCUSettings::Control control; - control.setEnable(on ? 1 : 0); + case F_TIMER: + if (itsTimer++ > WRITE_TIMEOUT && + Cache::getInstance().getState().crcontrol().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to write PPSsync settings register. Retrying..."); + stringstream ss; + Cache::getInstance().getState().crcontrol().print(ss); + LOG_DEBUG_STR("PPSsync failure state: " << ss); + TRAN(Sequencer::RSUclear_state); + } + else if (Cache::getInstance().getState().crcontrol().isMatchAll(RegisterState::IDLE)) { + TRAN(Sequencer::RCUenable_state); + } + break; - Cache::getInstance().getFront().getRCUSettings()() = control; - Cache::getInstance().getBack().getRCUSettings()() = control; + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::PPSsync_state"); + break; - Cache::getInstance().getState().rcusettings().reset(); - Cache::getInstance().getState().rcusettings().write(); -} + default: + break; + } -// -// RCUenable_state(event, port) -// -GCFEvent::TResult Sequencer::RCUenable_state(GCFEvent& event, GCFPortInterface& /*port*/) -{ - static bool waitForOddSecond(false); - - switch (event.signal) { - case F_ENTRY: { - LOG_INFO("Entering Sequencer::RCUenable_state"); - itsTimer = 0; - - // command may only be executed on even seconds for RTCP - // since the timestamp is always one second ahead we have - // to wait of an odd second (to end in the even second). - if (time(0) % 2 == 0) { - waitForOddSecond = true; - LOG_INFO("Wait for even second before enabling RCUs"); - break; - } - - waitForOddSecond = false; - LOG_INFO("Entry at even second, enabling RCUs immediately"); - enableRCUs(true); - } - break; - - case F_TIMER: { - if (waitForOddSecond) { - if (time(0) % 2 == 0) { - LOG_INFO("Still waiting for even second, missed pps?"); - break; - } - waitForOddSecond = false; - LOG_INFO("Enabling RCUs delayed till even second"); - enableRCUs(true); - break; - } - - // Command are sent, wait for command to complete. - if (itsTimer++ > WRITE_TIMEOUT && - Cache::getInstance().getState().rcusettings().getMatchCount(RegisterState::WRITE) > 0) { - LOG_WARN("Failed to enable receivers. Retrying..."); - TRAN(Sequencer::RSUclear_state); - } else if (Cache::getInstance().getState().rcusettings().isMatchAll(RegisterState::IDLE)) { - TRAN(Sequencer::CDOenable_state); - } - } - break; - - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::RCUenable_state"); - break; - - default: - break; - } - - return (GCFEvent::HANDLED); + return (GCFEvent::HANDLED); } // -// CDOenable_state(event, port) +// enableRCUs [private] // -GCFEvent::TResult Sequencer::CDOenable_state(GCFEvent& event, GCFPortInterface& /*port*/) +void Sequencer::enableRCUs(bool on) { - switch (event.signal) { - case F_ENTRY: - LOG_INFO("Entering Sequencer::CDOenable_state"); - Cache::getInstance().getState().cdo().reset(); - Cache::getInstance().getState().cdo().write(); - itsTimer = 0; - break; - - case F_TIMER: - if (itsTimer++ > WRITE_TIMEOUT && - Cache::getInstance().getState().rcusettings().getMatchCount(RegisterState::WRITE) > 0) { - LOG_WARN("Failed to enable receivers. Retrying..."); - TRAN(Sequencer::RSUclear_state); - } else if (Cache::getInstance().getState().rcusettings().isMatchAll(RegisterState::IDLE)) { - if (StationSettings::instance()->hasAartfaac()) { - TRAN(Sequencer::SDObitmode_state); - } - else { - itsFinalState = true; - TRAN(Sequencer::RCUdisable_state); - } - } - break; + RCUSettings::Control control; + control.setEnable(on ? 1 : 0); - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::CDOenable_state"); - break; + Cache::getInstance().getFront().getRCUSettings()() = control; + Cache::getInstance().getBack().getRCUSettings()() = control; - default: - break; - } - - return (GCFEvent::HANDLED); + Cache::getInstance().getState().rcusettings().reset(); + Cache::getInstance().getState().rcusettings().write(); } // -// CDOenable_state(event, port) +// RCUenable_state(event, port) // -GCFEvent::TResult Sequencer::SDObitmode_state(GCFEvent& event, GCFPortInterface& /*port*/) +GCFEvent::TResult Sequencer::RCUenable_state(GCFEvent& event, GCFPortInterface& /*port*/) { - int select; - int bits_per_sample; + static bool waitForOddSecond(false); + switch (event.signal) { - case F_ENTRY: - LOG_INFO("Entering Sequencer::SDObitmode_state"); - select = 0; - bits_per_sample = GET_CONFIG("RSPDriver.SDO_MODE", i); - if (bits_per_sample == 8) { select = 1; } - else if (bits_per_sample == 5) { select = 2; } - else if (bits_per_sample == 4) { select = 3; } - RSRSDOMode sdomodeinfo; - sdomodeinfo.bm_select = select; - sdomodeinfo.bm_max = 3; - for (int rsp = 0; rsp < StationSettings::instance()->nrRspBoards(); rsp++) { - Cache::getInstance().getBack().getSDOModeInfo()()(rsp) = sdomodeinfo; - Cache::getInstance().getFront().getSDOModeInfo()()(rsp) = sdomodeinfo; - } - Cache::getInstance().getState().sdoState().reset(); - Cache::getInstance().getState().sdoState().write(); - + case F_ENTRY: { + LOG_INFO("Entering Sequencer::RCUenable_state"); itsTimer = 0; - break; - case F_TIMER: - if (itsTimer++ > WRITE_TIMEOUT && Cache::getInstance().getState().sdoState().isMatchAll(RegisterState::IDLE)) { - //itsFinalState = true; - TRAN(Sequencer::SDOselect_state); - } - break; + // command may only be executed on even seconds for RTCP + // since the timestamp is always one second ahead we have + // to wait of an odd second (to end in the even second). + if (time(0) % 2 == 0) { + waitForOddSecond = true; + LOG_INFO("Wait for even second before enabling RCUs"); + break; + } - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::SDObitmode_state"); - break; + waitForOddSecond = false; + LOG_INFO("Entry at even second, enabling RCUs immediately"); + enableRCUs(true); + } + break; + + case F_TIMER: { + if (waitForOddSecond) { + if (time(0) % 2 == 0) { + LOG_INFO("Still waiting for even second, missed pps?"); + break; + } + waitForOddSecond = false; + LOG_INFO("Enabling RCUs delayed till even second"); + enableRCUs(true); + break; + } - default: - break; - } + // Command are sent, wait for command to complete. + if (itsTimer++ > WRITE_TIMEOUT && + Cache::getInstance().getState().rcusettings().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to enable receivers. Retrying..."); + TRAN(Sequencer::RSUclear_state); + } else if (Cache::getInstance().getState().rcusettings().isMatchAll(RegisterState::IDLE)) { + itsFinalState = true; + TRAN(Sequencer::RCUdisable_state); + //TRAN(Sequencer::CDOenable_state); + } + } + break; - return (GCFEvent::HANDLED); -} + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::RCUenable_state"); + break; -// default settings -// sdo_ss=295:330,331:366,367:402,403:438 -blitz::Array<uint16, 2> Sequencer::str2blitz(const char* str, int max) -{ - string inputstring(str); - char* start = (char*)inputstring.c_str(); - char* end = 0; - bool range = false; - long prevval = 0; - - blitz::Array<uint16, 2> ss(4,36); // ss = subband select - int bank_nr = 0; - int sb_nr = 0; - long i; - - ss = 0; - while (start) { - long val = strtol(start, &end, 10); // read decimal numbers - start = (end ? (*end ? end + 1 : 0) : 0); // advance - if (val >= max || val < 0) { - LOG_WARN(formatString("Error: value %ld out of range",val)); - ss = 0; - return ss; - } - LOG_INFO_STR("val=" << val << " prevval=" << prevval); - if (end) { - switch (*end) { - case ',': - case 0: { - if (range) { - if (0 == prevval && 0 == val) { - val = max - 1; - } - if (val < prevval) { - LOG_WARN("Error: invalid range specification"); - ss = 0; - return ss; - } - - for (i = prevval; i <= val; i++) { - //LOG_INFO(formatString("add value %ld to ss(%d,%d)", i, bank_nr, sb_nr)); - ss(bank_nr, sb_nr) = (uint16)i; - sb_nr++; - if (sb_nr >= 36) { - bank_nr++; - sb_nr = 0; - } - } - } - else { - ss(bank_nr, sb_nr) = (uint16)val; - sb_nr++; - if (sb_nr >= 36) { - bank_nr++; - sb_nr = 0; - } - } - range=false; - } break; - - case ':': { - range=true; - } break; - - default: { - LOG_WARN(formatString("Error: invalid character %c",*end)); - ss = 0; - return ss; - } break; - } // switch - } // if (end) - prevval = val; - } // while - - return (ss); + default: + break; + } + + return (GCFEvent::HANDLED); } // // CDOenable_state(event, port) // -GCFEvent::TResult Sequencer::SDOselect_state(GCFEvent& event, GCFPortInterface& /*port*/) +GCFEvent::TResult Sequencer::CDOenable_state(GCFEvent& event, GCFPortInterface& /*port*/) { - char select_str[64]; - int nBanks; - int pol; - blitz::Array<uint16, 2> select(4,36); - switch (event.signal) { - case F_ENTRY: - LOG_INFO("Entering Sequencer::SDOselect_state"); - strncpy(select_str, GET_CONFIG_STRING("RSPDriver.SDO_SS"), 64); - LOG_DEBUG_STR("select string = " << select_str); - select = str2blitz(select_str, 512); - LOG_DEBUG_STR("SDO select values = " << select); - nBanks = (MAX_BITS_PER_SAMPLE / MIN_BITS_PER_SAMPLE); // fill all banks - for (int rcu = 0; rcu < StationSettings::instance()->nrRcus(); rcu++) { - pol = rcu%2; - for (int bank = 0; bank < nBanks; bank++) { - Cache::getInstance().getBack().getSDOSelection().subbands()(rcu, bank, Range::all()) = 0; - for (int sb = 0; sb < 36; sb++) { - Cache::getInstance().getBack().getSDOSelection().subbands()(rcu, bank, sb) = (select(bank, sb) * 2) + pol; - Cache::getInstance().getFront().getSDOSelection().subbands()(rcu, bank, sb) = (select(bank, sb) * 2) + pol; - } // for each subband - } // for each bank - - if (rcu == 0) { - LOG_DEBUG_STR("cache->subbands.sdo ss(0) = " << Cache::getInstance().getBack().getSDOSelection().subbands()(0, Range::all(), Range::all())); - } - } // for each rcu - - Cache::getInstance().getState().sdoSelectState().reset(); - Cache::getInstance().getState().sdoSelectState().write(); - + case F_ENTRY: + LOG_INFO("Entering Sequencer::CDOenable_state"); + Cache::getInstance().getState().cdo().reset(); + Cache::getInstance().getState().cdo().write(); itsTimer = 0; break; - case F_TIMER: - if (itsTimer++ > WRITE_TIMEOUT && Cache::getInstance().getState().sdoSelectState().isMatchAll(RegisterState::IDLE)) { - //itsFinalState = true; - TRAN(Sequencer::SDOenable_state); - } - break; + case F_TIMER: + if (itsTimer++ > WRITE_TIMEOUT && + Cache::getInstance().getState().cdo().getMatchCount(RegisterState::WRITE) > 0) { + LOG_WARN("Failed to enable receivers. Retrying..."); + TRAN(Sequencer::RSUclear_state); + } else if (Cache::getInstance().getState().cdo().isMatchAll(RegisterState::IDLE)) { + if (StationSettings::instance()->hasAartfaac()) { + TRAN(Sequencer::setSDOwrite_state); + } + else { + itsFinalState = true; + TRAN(Sequencer::RCUdisable_state); + } + } + break; - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::SDOselect_state"); - break; + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::CDOenable_state"); + break; - default: - break; - } + default: + break; + } - return (GCFEvent::HANDLED); + return (GCFEvent::HANDLED); } // -// CDOenable_state(event, port) +// setSDOwrite_state(event, port) // -GCFEvent::TResult Sequencer::SDOenable_state(GCFEvent& event, GCFPortInterface& /*port*/) +GCFEvent::TResult Sequencer::setSDOwrite_state(GCFEvent& event, GCFPortInterface& /*port*/) { switch (event.signal) { - case F_ENTRY: - LOG_INFO("Entering Sequencer::SDOenable_state"); + case F_ENTRY: + LOG_INFO("Entering Sequencer::setSDOwrite_state"); + + Cache::getInstance().getState().sdoState().reset(); + Cache::getInstance().getState().sdoState().write(); + Cache::getInstance().getState().sdoSelectState().reset(); + Cache::getInstance().getState().sdoSelectState().write(); + for (int blp_nr = 0; blp_nr < StationSettings::instance()->nrBlps(); blp_nr += 4) { - Cache::getInstance().getBack().getBypassSettings()()(blp_nr).setSDO(1); - Cache::getInstance().getFront().getBypassSettings()()(blp_nr).setSDO(1); Cache::getInstance().getState().bypasssettings().reset(blp_nr); Cache::getInstance().getState().bypasssettings().write(blp_nr); } - itsTimer = 0; - break; - - case F_TIMER: - if (itsTimer++ > WRITE_TIMEOUT && Cache::getInstance().getState().bypasssettings().isMatchAll(RegisterState::IDLE)) { - itsFinalState = true; - TRAN(Sequencer::RCUdisable_state); - } - break; + itsFinalState = true; + TRAN(Sequencer::RCUdisable_state); + break; - case F_EXIT: - LOG_DEBUG("Leaving Sequencer::SDOenable_state"); - break; + case F_TIMER: + break; - default: - break; - } + case F_EXIT: + LOG_DEBUG("Leaving Sequencer::setSDOwrite_state"); + break; - return (GCFEvent::HANDLED); + default: + break; + } + return (GCFEvent::HANDLED); } - } // namespace RSP } // namespace LOFAR diff --git a/MAC/APL/PIC/RSP_Driver/src/Sequencer.h b/MAC/APL/PIC/RSP_Driver/src/Sequencer.h index a7e5f112d06e04a1357980480ffdd8c0845d204e..ee2215f6542aa8dd106e7317c0ed93900a458431 100644 --- a/MAC/APL/PIC/RSP_Driver/src/Sequencer.h +++ b/MAC/APL/PIC/RSP_Driver/src/Sequencer.h @@ -38,71 +38,75 @@ namespace LOFAR { class Sequencer : public GCFFsm { public: - typedef enum { - SEQ_NONE = 0, - SEQ_SETCLOCK, // done at initialization - SEQ_RSPCLEAR, - SEQ_SDOPRESET, - } Sequence; - // - // Constructor/destructor - // - static Sequencer& getInstance(); - virtual ~Sequencer(); + typedef enum { + SEQ_NONE = 0, + SEQ_STARTUP, // done at initialization + SEQ_SETCLOCK, // if clock switch + SEQ_RSPCLEAR, + } Sequence; + // + // Constructor/destructor + // + static Sequencer& getInstance(); + virtual ~Sequencer(); - // - // Advance the sequencer state machine - // - void run(GCFEvent& event, GCFPortInterface& port); + // + // Advance the sequencer state machine + // + void run(GCFEvent& event, GCFPortInterface& port); - // - // Returns true when the statemachine is not in the 'idle' state. - // - bool isActive() const; + // + // Returns true when the statemachine is not in the 'idle' state. + // + bool isActive() const; - void startSequence(Sequence sequence) { itsCurSeq = sequence; } - void stopSequence() { itsCurSeq = SEQ_NONE; } + void startSequence(Sequence sequence) { itsCurSeq = sequence; } + void stopSequence() { itsCurSeq = SEQ_NONE; } - /*@{*/ - // - // The states of the statemachine. - // - GCFEvent::TResult idle_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult RSUpreclear_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult clearClock_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult writeClock_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult readClock_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult RCUdisable_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult RSUclear_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult setBlocksync_state(GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult RADwrite_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult PPSsync_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult RCUenable_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult CDOenable_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult SDObitmode_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult SDOselect_state (GCFEvent& event, GCFPortInterface& port); - GCFEvent::TResult SDOenable_state (GCFEvent& event, GCFPortInterface& port); - /*@}*/ + /*@{*/ + // + // The states of the statemachine. + // + GCFEvent::TResult idle_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult disableClock_state(GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult readDisabledClock_state(GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult writePLL_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult readPLL_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult RSUpreclear_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult clearClock_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult writeClock_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult readClock_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult RCUdisable_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult RSUclear_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult setAll_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult setBlocksync_state(GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult RADwrite_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult PPSsync_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult RCUenable_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult CDOenable_state (GCFEvent& event, GCFPortInterface& port); + GCFEvent::TResult setSDOwrite_state (GCFEvent& event, GCFPortInterface& port); + /*@}*/ private: - // - // Default construction prohibited (singleton pattern). - // - Sequencer(); - void enableRCUs(bool); + // + // Default construction prohibited (singleton pattern). + // + Sequencer(); + void enableRCUs(bool); blitz::Array<uint16, 2> str2blitz(const char* str, int max); //std::list<int> strtolist(const char* str, int max); - static Sequencer* m_instance; + static Sequencer* m_instance; - bool itsIdle; // In idle-state or not - Sequence itsCurSeq; // currently executing sequence + bool itsIdle; // In idle-state or not + Sequence itsCurSeq; // currently executing sequence + int itsClockRequest;// requested clock freq - int itsTimer; // timer used to delay some actions - bool itsFinalState; // final state of sequence (used by rcudisable_state) + int itsTimer; // timer used to delay some actions + bool itsFinalState; // final state of sequence (used by rcudisable_state) }; }; }; - + #endif /* SEQUENCER_H_ */ diff --git a/MAC/APL/PIC/RSP_Driver/src/SetRCUCmd.cc b/MAC/APL/PIC/RSP_Driver/src/SetRCUCmd.cc index 8dc8a920fbc0f62a2141d8d15b55cfc341e9119d..c61ec06ef62d98af04a19b029703fb98ee813c73 100644 --- a/MAC/APL/PIC/RSP_Driver/src/SetRCUCmd.cc +++ b/MAC/APL/PIC/RSP_Driver/src/SetRCUCmd.cc @@ -38,85 +38,94 @@ using namespace RSP_Protocol; using namespace RTC; SetRCUCmd::SetRCUCmd(GCFEvent& event, GCFPortInterface& port, Operation oper) : - Command("SetRCU", port, oper) + Command("SetRCU", port, oper) { - m_event = new RSPSetrcuEvent(event); + m_event = new RSPSetrcuEvent(event); - LOG_INFO(formatString("control=0x%08x", m_event->settings()(0).getRaw())); + LOG_INFO(formatString("control=0x%08x", m_event->settings()(0).getRaw())); } SetRCUCmd::~SetRCUCmd() { - delete m_event; + delete m_event; } void SetRCUCmd::ack(CacheBuffer& /*cache*/) { - RSPSetrcuackEvent ack; - ack.timestamp = getTimestamp(); - ack.status = RSP_SUCCESS; - getPort()->send(ack); + RSPSetrcuackEvent ack; + ack.timestamp = getTimestamp(); + ack.status = RSP_SUCCESS; + getPort()->send(ack); } void SetRCUCmd::apply(CacheBuffer& cache, bool setModFlag) { - // someone else using the I2C bus? - I2Cuser busUser = cache.getI2Cuser(); - LOG_INFO_STR("SetRCU::apply : " << ((busUser == NONE) ? "NONE" : - ((busUser == HBA) ? "HBA" : - ((busUser == RCU_R) ? "RCU_R" : "RCU_W")))); - if (busUser != NONE && busUser != RCU_W) { - postponeExecution(true); - return; - } - cache.setI2Cuser(RCU_W); // claim the I2C bus. - postponeExecution(false); - - bool newMode = m_event->settings()(0).isModeModified(); - uint32 mode = m_event->settings()(0).getMode(); - CableSettings* cableSettings = CableSettings::instance(); - float delayStep = 1000.0 / cache.getClock(); + // someone else using the I2C bus? + I2Cuser busUser = cache.getI2Cuser(); + LOG_INFO_STR("SetRCU::apply : " << ((busUser == NONE) ? "NONE" : + ((busUser == HBA) ? "HBA" : + ((busUser == RCU_R) ? "RCU_R" : "RCU_W")))); + if (busUser != NONE && busUser != RCU_W) { + postponeExecution(true); + return; + } + cache.setI2Cuser(RCU_W); // claim the I2C bus. + postponeExecution(false); + + bool newMode = m_event->settings()(0).isModeModified(); + uint32 mode = m_event->settings()(0).getMode(); + CableSettings* cableSettings = CableSettings::instance(); + float delayStep = 1000.0 / cache.getClock(); // LOG_INFO("SetRCUCmd::apply"); - for (int cache_rcu = 0; cache_rcu < StationSettings::instance()->nrRcus(); cache_rcu++) { - if (m_event->rcumask[cache_rcu]) { - // make change - cache.getRCUSettings()()(cache_rcu) = m_event->settings()(0); - - // Apply delays and attenuation when mode was changed. - if (newMode) { - cache.getRCUSettings()()(cache_rcu).setDelay( - (uint8) ((delayStep/2.0 + cableSettings->getDelay(cache_rcu, mode)) / delayStep)); - cache.getRCUSettings()()(cache_rcu).setAttenuation( - (uint8) ((-0.125 + cableSettings->getAtt(cache_rcu, mode)) / -0.25)); - if (cache_rcu == 0) { - LOG_DEBUG(formatString("RCU 0 new Delay : %f/2.0 + %f / %f = %d", - delayStep, cableSettings->getDelay(0, mode), delayStep, - (uint8) ((delayStep/2.0 + cableSettings->getDelay(cache_rcu, mode)) / delayStep))); - LOG_DEBUG(formatString("RCU 0 new Atten : -0.125 + %f / -0.25 = %d", cableSettings->getAtt(0, mode), - (uint8) ((-0.125 + cableSettings->getAtt(cache_rcu, mode)) / -0.25))); - LOG_DEBUG(formatString("RCU 0 new RawMode : %08lX", cache.getRCUSettings()()(0).getRaw())); - } - } - - if (setModFlag) { - // only write RCU Handler settings if modified - if (m_event->settings()(0).isHandlerModified()) { - cache.getCache().getState().rcusettings().write(cache_rcu); - } - - // only write RCU Protocol settings if modified - if (m_event->settings()(0).isProtocolModified()) { - cache.getCache().getState().rcuprotocol().write(cache_rcu); - } - } - } // if in mask - } // for + for (int cache_rcu = 0; cache_rcu < StationSettings::instance()->nrRcus(); cache_rcu++) { + if (m_event->rcumask[cache_rcu]) { + // make change + cache.getRCUSettings()()(cache_rcu) = m_event->settings()(0); + + // Apply delays and attenuation when mode was changed. + if (newMode) { + // if mode changed be sure RCU is enabled, is needed to reduce poweron current on hba's + /* + if (mode > 0) { + cache.getRCUSettings()()(cache_rcu).setEnable(1); + } + else { + cache.getRCUSettings()()(cache_rcu).setEnable(0); + } + */ + cache.getRCUSettings()()(cache_rcu).setDelay( + (uint8) ((delayStep/2.0 + cableSettings->getDelay(cache_rcu, mode)) / delayStep)); + cache.getRCUSettings()()(cache_rcu).setAttenuation( + (uint8) ((-0.125 + cableSettings->getAtt(cache_rcu, mode)) / -0.25)); + if (cache_rcu == 0) { + LOG_DEBUG(formatString("RCU 0 new Delay : %f/2.0 + %f / %f = %d", + delayStep, cableSettings->getDelay(0, mode), delayStep, + (uint8) ((delayStep/2.0 + cableSettings->getDelay(cache_rcu, mode)) / delayStep))); + LOG_DEBUG(formatString("RCU 0 new Atten : -0.125 + %f / -0.25 = %d", cableSettings->getAtt(0, mode), + (uint8) ((-0.125 + cableSettings->getAtt(cache_rcu, mode)) / -0.25))); + LOG_DEBUG(formatString("RCU 0 new RawMode : %08lX", cache.getRCUSettings()()(0).getRaw())); + } + } + + if (setModFlag) { + // only write RCU Handler settings if modified + if (m_event->settings()(0).isHandlerModified()) { + cache.getCache().getState().rcusettings().write(cache_rcu); + } + + // only write RCU Protocol settings if modified + if (m_event->settings()(0).isProtocolModified()) { + cache.getCache().getState().rcuprotocol().write(cache_rcu); + } + } + } // if in mask + } // for } void SetRCUCmd::complete(CacheBuffer& cache) { - ack(cache); + ack(cache); } const Timestamp& SetRCUCmd::getTimestamp() const @@ -132,6 +141,6 @@ void SetRCUCmd::setTimestamp(const Timestamp& timestamp) bool SetRCUCmd::validate() const { return ((m_event->rcumask.count() <= (unsigned int)StationSettings::instance()->nrRcus()) - && (1 == m_event->settings().dimensions()) - && (1 == m_event->settings().extent(firstDim))); + && (1 == m_event->settings().dimensions()) + && (1 == m_event->settings().extent(firstDim))); } diff --git a/MAC/APL/PIC/RSP_Driver/src/StatusRead.cc b/MAC/APL/PIC/RSP_Driver/src/StatusRead.cc index 4f97904165a54967310f578725c82e155a6ef336..c6c2c77409a13ba1d1478ca95f91a8c59be6584d 100644 --- a/MAC/APL/PIC/RSP_Driver/src/StatusRead.cc +++ b/MAC/APL/PIC/RSP_Driver/src/StatusRead.cc @@ -42,6 +42,9 @@ StatusRead::StatusRead(GCFPortInterface& board_port, int board_id) : SyncAction(board_port, board_id, 1) { memset(&m_hdr, 0, sizeof(MEPHeader)); + + // this action should be performed at initialisation + //doAtInit(); } StatusRead::~StatusRead() @@ -110,26 +113,29 @@ GCFEvent::TResult StatusRead::handleack(GCFEvent& event, GCFPortInterface& /*por // if cache value different from hardware reported value, make equal switch (ack.board.rsp.bp_clock) { + case 125: case 160: case 200: if (0 == getBoardId()) { if (0 == Cache::getInstance().getBack().getClock()) { + #if 0 - LOG_INFO_STR(formatString("Receiving initial clock setting from RSP board: %d MHz. Adjusting cache value.", - ack.board.rsp.bp_clock)); - Cache::getInstance().getFront().getClock() = ack.board.rsp.bp_clock; - Cache::getInstance().getBack().getClock() = ack.board.rsp.bp_clock; + LOG_INFO_STR(formatString("Receiving initial clock setting from RSP board: %d MHz. Adjusting cache value.", + ack.board.rsp.bp_clock)); + Cache::getInstance().getFront().getClock() = ack.board.rsp.bp_clock; + Cache::getInstance().getBack().getClock() = ack.board.rsp.bp_clock; #endif + } else if (ack.board.rsp.bp_clock != Cache::getInstance().getBack().getClock()) { - LOG_WARN_STR(formatString("Reported clock (%d MHz) is different from cache settings (%d MHz) on RSP board %d", - ack.board.rsp.bp_clock, Cache::getInstance().getBack().getClock(), getBoardId())); + LOG_WARN_STR(formatString("Reported clock (%d MHz) is different from cache settings (%d MHz) on RSP board %d", + ack.board.rsp.bp_clock, Cache::getInstance().getBack().getClock(), getBoardId())); } } break; default: LOG_WARN_STR(formatString("Invalid clock setting received from RSP board (%d): %d MHz", - getBoardId(), ack.board.rsp.bp_clock)); + getBoardId(), ack.board.rsp.bp_clock)); break; } diff --git a/MAC/APL/PIC/RSP_Driver/src/TDSProtocolWrite.cc b/MAC/APL/PIC/RSP_Driver/src/TDSProtocolWrite.cc index ae714c4307adc0bfdc5eb43f2bba7ef255d5d792..4036cff380290b417cc02813fd124856e02824d2 100644 --- a/MAC/APL/PIC/RSP_Driver/src/TDSProtocolWrite.cc +++ b/MAC/APL/PIC/RSP_Driver/src/TDSProtocolWrite.cc @@ -46,97 +46,83 @@ using namespace EPA_Protocol; namespace LOFAR { namespace RSP { + static uint8 tds_pll[ + TDS_INIT_SIZE + + TDS_PROGRAMPLLS_SIZE] = { + + // program pll + TDS_INIT, + TDS_PROGRAMPLLS, + }; + + uint8 tds_pll_result[ + TDS_INIT_RESULT_SIZE + + TDS_PROGRAMPLLS_RESULT_SIZE] = { + + TDS_INIT_RESULT, + TDS_PROGRAMPLLS_RESULT, + }; + + static uint8 tds_160MHz[ -#ifndef DISABLE_PROGRAMPLL - TDS_INIT_SIZE - + TDS_PROGRAMPLLS_SIZE -#endif - + TDS_160MHZ_SIZE - + TDS_C_END_SIZE] = { - - // switch to 160MHz to backplane (using 10MHz reference at the front) -#ifndef DISABLE_PROGRAMPLL - TDS_INIT, - TDS_PROGRAMPLLS, -#endif - TDS_160MHZ, - TDS_C_END, - - }; - + TDS_160MHZ_SIZE + + TDS_C_END_SIZE] = { + + // switch to 160MHz to backplane (using 10MHz reference at the front) + TDS_160MHZ, + TDS_C_END, + + }; + uint8 tds_160MHz_result[ -#ifndef DISABLE_PROGRAMPLL - TDS_INIT_RESULT_SIZE - + TDS_PROGRAMPLLS_RESULT_SIZE -#endif - + TDS_160MHZ_RESULT_SIZE - + TDS_C_END_RESULT_SIZE] = { - -#ifndef DISABLE_PROGRAMPLL - TDS_INIT_RESULT, - TDS_PROGRAMPLLS_RESULT, -#endif - TDS_160MHZ_RESULT, - TDS_C_END_RESULT, - - }; - - static uint8 tds_200MHz[ -#ifndef DISABLE_PROGRAMPLL - TDS_INIT_SIZE - + TDS_PROGRAMPLLS_SIZE -#endif - + TDS_200MHZ_SIZE - + TDS_C_END_SIZE] = { - - // switch to 200MHz to backplane (using 10MHz reference at the front) -#ifndef DISABLE_PROGRAMPLL - TDS_INIT, - TDS_PROGRAMPLLS, -#endif - TDS_200MHZ, - TDS_C_END, - - }; + TDS_160MHZ_RESULT_SIZE + + TDS_C_END_RESULT_SIZE] = { + + TDS_160MHZ_RESULT, + TDS_C_END_RESULT, + + }; + + static uint8 tds_200MHz[ + TDS_200MHZ_SIZE + + TDS_C_END_SIZE] = { + + // switch to 200MHz to backplane (using 10MHz reference at the front) + TDS_200MHZ, + TDS_C_END, + + }; uint8 tds_200MHz_result[ -#ifndef DISABLE_PROGRAMPLL - TDS_INIT_RESULT_SIZE - + TDS_PROGRAMPLLS_RESULT_SIZE -#endif - + TDS_200MHZ_RESULT_SIZE - + TDS_C_END_RESULT_SIZE] = { - -#ifndef DISABLE_PROGRAMPLL - TDS_INIT_RESULT, - TDS_PROGRAMPLLS_RESULT, -#endif - TDS_200MHZ_RESULT, - TDS_C_END_RESULT, - - }; + + TDS_200MHZ_RESULT_SIZE + + TDS_C_END_RESULT_SIZE] = { + + TDS_200MHZ_RESULT, + TDS_C_END_RESULT, + + }; static uint8 tds_off[ TDS_VCXO_OFF_SIZE - + TDS_OFF_SIZE - + TDS_C_END_SIZE] = { + + TDS_OFF_SIZE + + TDS_C_END_SIZE] = { - // switch off clock to backplane, RSP should switch to 125MHz - TDS_VCXO_OFF, - TDS_OFF, - TDS_C_END, + // switch off clock to backplane, RSP should switch to 125MHz + TDS_VCXO_OFF, + TDS_OFF, + TDS_C_END, - }; + }; uint8 tds_off_result[ TDS_VCXO_OFF_RESULT_SIZE - + TDS_OFF_RESULT_SIZE - + TDS_C_END_RESULT_SIZE] = { + + TDS_OFF_RESULT_SIZE + + TDS_C_END_RESULT_SIZE] = { - TDS_VCXO_OFF_RESULT, - TDS_OFF_RESULT, - TDS_C_END_RESULT, + TDS_VCXO_OFF_RESULT, + TDS_OFF_RESULT, + TDS_C_END_RESULT, - }; + }; }; }; @@ -180,6 +166,11 @@ void TDSProtocolWrite::sendrequest() size_t size = 0; + // select clock + // 160 or 200 [MHz] (extern td clock) + // 125 [MHz] (intern board clock) + // 0 programm pll + switch (Cache::getInstance().getBack().getClock()) { case 160: buf = (char*)tds_160MHz; @@ -201,7 +192,7 @@ void TDSProtocolWrite::sendrequest() tdsprotocol.hdr.set(MEPHeader::TDS_PROTOCOL_HDR, MEPHeader::DST_RSP, MEPHeader::WRITE, size, m_offset); break; - default: + case 125: buf = (char*)tds_off; if (0 == getCurrentIndex()) { m_remaining = sizeof(tds_off); @@ -210,13 +201,23 @@ void TDSProtocolWrite::sendrequest() size = MIN(TDS_CHUNK_SIZE, m_remaining); tdsprotocol.hdr.set(MEPHeader::TDS_PROTOCOL_HDR, MEPHeader::DST_RSP, MEPHeader::WRITE, size, m_offset); break; + + default: + buf = (char*)tds_pll; + if (0 == getCurrentIndex()) { + m_remaining = sizeof(tds_pll); + m_offset = 0; + } + size = MIN(TDS_CHUNK_SIZE, m_remaining); + tdsprotocol.hdr.set(MEPHeader::TDS_PROTOCOL_HDR, MEPHeader::DST_RSP, MEPHeader::WRITE, size, m_offset); + break; } tdsprotocol.protocol.setBuffer((char*)buf + m_offset, size); // indicate that we're initialising the hardware LOG_INFO_STR(formatString("Sending clock setting (offset=%d) via RSP board %d: %d MHz", - m_offset, getBoardId(), Cache::getInstance().getBack().getClock())); + m_offset, getBoardId(), Cache::getInstance().getBack().getClock())); // advance m_remaining -= size; @@ -239,7 +240,7 @@ GCFEvent::TResult TDSProtocolWrite::handleack(GCFEvent& event, GCFPortInterface& LOG_WARN("TDSProtocolWrite::handleack:: unexpected ack"); return GCFEvent::NOT_HANDLED; } - + EPAWriteackEvent ack(event); if (!ack.hdr.isValidAck(m_hdr)) diff --git a/MAC/APL/PIC/RSP_Driver/src/TDSi2cdefs.h b/MAC/APL/PIC/RSP_Driver/src/TDSi2cdefs.h index aff9a79d53c366e9923ccad9f3c51e35ed368381..1c20f0f584023a438be44230124316bcea3c6a90 100644 --- a/MAC/APL/PIC/RSP_Driver/src/TDSi2cdefs.h +++ b/MAC/APL/PIC/RSP_Driver/src/TDSi2cdefs.h @@ -404,30 +404,24 @@ namespace LOFAR { namespace RSP { - extern uint8 tds_160MHz_result[ -#ifndef DISABLE_PROGRAMPLL - TDS_INIT_RESULT_SIZE - + TDS_PROGRAMPLLS_RESULT_SIZE -#endif - + TDS_160MHZ_RESULT_SIZE - + TDS_C_END_RESULT_SIZE]; - - extern uint8 tds_200MHz_result[ -#ifndef DISABLE_PROGRAMPLL - TDS_INIT_RESULT_SIZE - + TDS_PROGRAMPLLS_RESULT_SIZE -#endif - + TDS_200MHZ_RESULT_SIZE - + TDS_C_END_RESULT_SIZE]; - - extern uint8 tds_off_result[ TDS_VCXO_OFF_RESULT_SIZE - + TDS_OFF_RESULT_SIZE - + TDS_C_END_RESULT_SIZE]; + + extern uint8 tds_pll_result[ TDS_INIT_RESULT_SIZE + + TDS_PROGRAMPLLS_RESULT_SIZE ]; + + extern uint8 tds_160MHz_result[ TDS_160MHZ_RESULT_SIZE + + TDS_C_END_RESULT_SIZE ]; + + extern uint8 tds_200MHz_result[ TDS_200MHZ_RESULT_SIZE + + TDS_C_END_RESULT_SIZE ]; + + extern uint8 tds_off_result[ TDS_VCXO_OFF_RESULT_SIZE + + TDS_OFF_RESULT_SIZE + + TDS_C_END_RESULT_SIZE ]; extern uint8 tds_readstatus_result[ TDS_READ_LOCKDETECT_RESULT_SIZE + TDS_READ_VOLT_RESULT_SIZE + TDS_READ_SPU_RESULT_SIZE - + TDS_C_END_RESULT_SIZE]; + + TDS_C_END_RESULT_SIZE ]; }; }; diff --git a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/RCUSettings.h b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/RCUSettings.h index 5c882fddec71d25dd221993f51680e2f6e09e9c3..5f7faf0099c6c93abd0b7dfceb9de8da529e4c74 100644 --- a/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/RCUSettings.h +++ b/MAC/APL/PIC/RSP_Protocol/include/APL/RSP_Protocol/RCUSettings.h @@ -37,268 +37,268 @@ namespace LOFAR { namespace RSP_Protocol { // Note: The rcucontrol value is presented in the user interface as an uint32 value. -// This is the m_value byte that is stored in the Control (sub)class. Unfortunately -// this value can be written to one register on the RSPboards. The lowest byte -// (value & RCU_HANDLER_MASK) must be written to one register and the highest part -// (value & RCU_PROTOCOL_MASK) must be written to an i2c register. -// To know which write-actions must be performed the Control class keeps track of a -// m_modified mask that knows which bits where modified. -// The Commands that apply the RCUsetting to the cache use this mask to determine -// which write-actions must be triggered. +// This is the m_value byte that is stored in the Control (sub)class. Unfortunately +// this value can be written to one register on the RSPboards. The lowest byte +// (value & RCU_HANDLER_MASK) must be written to one register and the highest part +// (value & RCU_PROTOCOL_MASK) must be written to an i2c register. +// To know which write-actions must be performed the Control class keeps track of a +// m_modified mask that knows which bits where modified. +// The Commands that apply the RCUsetting to the cache use this mask to determine +// which write-actions must be triggered. class RCUSettings { public: - RCUSettings() {} - virtual ~RCUSettings() {} - - class Control - { - public: - Control() : m_value(0x00000000), m_modified(0x00000000) {} - - // no virtual to prevent creation of virtual pointer table - // which adds to the size of the struct - ~Control() {} - - typedef enum { - MODE_OFF = 0, // 0x00000000 - MODE_LBL_HPF10MHZ = 1, // 0x00017900 - MODE_LBL_HPF30MHZ = 2, // 0x00057900 - MODE_LBH_HPF10MHZ = 3, // 0x00037A00 - MODE_LBH_HPF30MHZ = 4, // 0x00077A00 - MODE_HB_110_190MHZ = 5, // 0x0007A400 - MODE_HB_170_230MHZ = 6, // 0x00079400 - MODE_HB_210_290MHZ = 7, // 0x00078400 - } RCUMode; - static const int N_MODES = 8; - - // Set the mode of the receiver. - void setMode(RCUMode mode) { - m_value &= ~MODE_MASK; // clear mode bits - m_value |= (m_mode[mode % N_MODES] & MODE_MASK); // set new mode bits - m_modified |= MODE_MASK; - } - int getMode() { - switch (m_value & MODE_MASK) { - case 0x00003000: return(0); - case 0x00017900: return(1); - case 0x00057900: return(2); - case 0x00037A00: return(3); - case 0x00077A00: return(4); - case 0x0007A400: return(5); - case 0x00079400: return(6); - case 0x00078400: return(7); - default: return (-1); - } - } - bool isModeOff() { - return !(m_value & MODE_MASK); - } - bool isModeModified() { - return (m_modified & MODE_MASK); - } - - // Return the number of the Nyquist zone for the - // current receiver setting. - // 0 = indeterminate - // 1 = Nyquist zone I - // 2 = Nyquist zone II - // 3 = Nyquist zone III - int getNyquistZone() const; - - bool LBAfilter() const { return (!HBAinput() && (m_value & _30MHZ_MASK)); } - - bool LBLinput() const { return ((m_value & INPUT_SEL) == (LBL_EN | BANDSEL | VL_EN)); } - bool LBHinput() const { return ((m_value & INPUT_SEL) == (LBH_EN | BANDSEL | VL_EN)); } - bool HBAinput() const { return ((m_value & INPUT_SEL) == (HB_EN | VH_EN)); } - - // Set the raw control bytes of a RCU - // Each RCU has 4 bytes: - // mask meaning explanation - // 0x0000007F INPUT_DELAY Sample delay for the data from the RCU. - // 0x00000080 INPUT_ENABLE Enable RCU input - // - // 0x00000100 LBL-EN supply LBL antenna on (1) or off (0) - // 0x00000200 LBH-EN sypply LBH antenna on (1) or off (0) - // 0x00000400 HB-EN supply HB on (1) or off (0) - // 0x00000800 BANDSEL low band (1) or high band (0) - // 0x00001000 HB-SEL-0 HBA filter selection - // 0x00002000 HB-SEL-1 HBA filter selection - // Options : HBA-SEL-0 HBA-SEL-1 Function - // 0 0 210-270 MHz - // 0 1 170-230 MHz - // 1 0 110-190 MHz - // 1 1 all off - // 0x00004000 VL-EN low band supply on (1) or off (0) - // 0x00008000 VH-EN high band supply on (1) or off (0) - // - // 0x00010000 VDIG-EN ADC supply on (1) or off (0) - // 0x00020000 LB-SEL-0 LBA input selection - // 0x00040000 LB-SEL-1 HP filter selection - // Options : LB-SEL-0 LB-SEL-1 Function - // 0 0 10-90 MHz + 10 MHz HPF - // 0 1 30-80 MHz + 10 MHz HPF - // 1 0 10-90 MHz + 30 MHz HPF - // 1 1 30-80 MHz + 30 MHz HPF - // 0x00080000 ATT-CNT-4 on (1) is 1dB attenuation - // 0x00100000 ATT-CNT-3 on (1) is 2dB attenuation - // 0x00200000 ATT-CNT-2 on (1) is 4dB attenuation - // 0x00300000 ATT-CNT-1 on (1) is 8dB attenuation - // 0x00800000 ATT-CNT-0 on (1) is 16dB attenuation - // - // 0x01000000 PRSG pseudo random sequence generator on (1), off (0) - // 0x02000000 RESET on (1) hold board in reset - // 0x04000000 free used to be SPEC_INV, SI now in DIAG/Bypass - // 0x08000000 TBD reserved - // 0xF0000000 VERSION RCU version //PD - void setRaw(uint32 raw) { m_value = raw; m_modified = 0xFFFFFFFF; } - uint32 getRaw() const { return m_value; } - // set protocol part of the raw byte - void setProtocolRaw(uint32 raw) { - m_value = (m_value & RCU_HANDLER_MASK) | (raw & RCU_PROTOCOL_MASK); - m_modified = RCU_PROTOCOL_MASK; - } - - // Enable (true) or disable (false) pseudo random sequence generator. - void setPRSG(bool value) { - if (value) m_value |= PRSG_MASK; // set PRSG bit - else m_value &= ~PRSG_MASK; // clear PRSG bit - m_modified |= PRSG_MASK; - } - bool getPRSG() const { return (m_value & PRSG_MASK) >> (16 + 8); } - - // Enable (true) or disable (false) reset on RCU. - void setReset(bool value) { - if (value) m_value |= RESET_MASK; // set RESET bit - else m_value &= ~RESET_MASK; // clear RESET bit - m_modified |= RESET_MASK; - } - bool getReset() const { return (m_value & RESET_MASK) >> (17 + 8); } - - // Set attenuation. Valid values are 0..31 (5 bits). - void setAttenuation(uint8 value) { - // useful bits should be is in lower 5 bits - value &= 0x1F; - m_value &= ~ATT_MASK; // clear mode bits - // cast value to uint32 to allow << 11, set new mode bits - m_value |= (((uint32)value << (11 + 8)) & ATT_MASK); - m_modified |= ATT_MASK; - } - uint8 getAttenuation() const { return (m_value & ATT_MASK) >> (11 + 8); } - - // Set sample delay (true time delay). Valid values are 0..127 (7 bits) - void setDelay(uint8 value) { - m_value &= ~DELAY_MASK; - m_value |= (value & DELAY_MASK); - m_modified |= DELAY_MASK; - } - uint8 getDelay() const { return m_value & DELAY_MASK; } - - // Set rcu enable (0 = disable, 1 = enable) - void setEnable(uint8 value) { - if (value) m_value |= ENABLE_MASK; // set ENABLE bit - else m_value &= ~ENABLE_MASK; // clear ENABLE bit - m_modified |= ENABLE_MASK; - } - bool getEnable() const { return m_value & ENABLE_MASK; } - - // Set rcu version //PD - void setVersion(uint8 value) { - m_value &= ~VERSION_MASK; // clear VERSION bit - if (value) m_value |= ((value & 0x0F) << (20 + 8)); // set VERSION bits - m_modified |= VERSION_MASK; - } - uint8 getVersion() const { return (m_value & VERSION_MASK) >> (20 + 8); } - - // Get RCU handler and RCU protocol settings separately - bool isHandlerModified() { return (m_modified & RCU_HANDLER_MASK); } - bool isProtocolModified() { return (m_modified & RCU_PROTOCOL_MASK); } - bool isEnableModified() { return (m_modified & ENABLE_MASK); } - - // Reset value and modified mask. - void reset() { - m_value = 0x00000000; - m_modified = 0x00000000; - } - - // Return modification mask - uint32 getModified() const { return m_modified; } - - // Assignment - Control& operator=(const Control& rhs) { - if (this != &rhs) { // prevent self-assignment - m_value &= ~rhs.m_modified; // clear the modified bits - m_value |= (rhs.m_value & rhs.m_modified); // set the modified bits with new values - m_modified |= rhs.m_modified; // combine the masks - } - return *this; - } - - // Copy constructor - Control(const Control& rhs) { - this->reset(); // reset m_value and m_modified - *this = rhs; - } - - // print function for operator<< - ostream& print (ostream& os) const - { os << formatString("%08X", m_value); return (os); } - - private: - // constants used to set the appropriate mode - static const uint32 m_mode[]; - - // masks used to set/get bits - static const uint32 DELAY_MASK = 0x0000007F; - static const uint32 ENABLE_MASK = 0x00000080; - static const uint32 _30MHZ_MASK = 0x00040000; - static const uint32 MODE_MASK = 0x0007FF00; - static const uint32 ATT_MASK = 0x00F80000; - static const uint32 PRSG_MASK = 0x01000000; - static const uint32 RESET_MASK = 0x02000000; - static const uint32 SPECINV_MASK = 0x04000000; - static const uint32 VERSION_MASK = 0xF0000000; //PD - - static const uint32 LBL_EN = 0x00000100; - static const uint32 LBH_EN = 0x00000200; - static const uint32 HB_EN = 0x00000400; - static const uint32 BANDSEL = 0x00000800; - static const uint32 VL_EN = 0x00004000; - static const uint32 VH_EN = 0x00008000; - static const uint32 INPUT_SEL = 0x0000CF00; - - static const uint32 RCU_HANDLER_MASK = 0x000000FF; - static const uint32 RCU_PROTOCOL_MASK = 0xFFFFFF00; - - // ----- datamembers ----- - uint32 m_value; - uint32 m_modified; // mask of modified bits - }; // class Control - - /* get reference settings array */ - blitz::Array<Control, 1>& operator()(); + RCUSettings() {} + virtual ~RCUSettings() {} + + class Control + { + public: + Control() : m_value(0x00000000), m_modified(0x00000000) {} + + // no virtual to prevent creation of virtual pointer table + // which adds to the size of the struct + ~Control() {} + + typedef enum { + MODE_OFF = 0, // 0x00000000 + MODE_LBL_HPF10MHZ = 1, // 0x00017900 + MODE_LBL_HPF30MHZ = 2, // 0x00057900 + MODE_LBH_HPF10MHZ = 3, // 0x00037A00 + MODE_LBH_HPF30MHZ = 4, // 0x00077A00 + MODE_HB_110_190MHZ = 5, // 0x0007A400 + MODE_HB_170_230MHZ = 6, // 0x00079400 + MODE_HB_210_290MHZ = 7, // 0x00078400 + } RCUMode; + static const int N_MODES = 8; + + // Set the mode of the receiver. + void setMode(RCUMode mode) { + m_value &= ~MODE_MASK; // clear mode bits + m_value |= (m_mode[mode % N_MODES] & MODE_MASK); // set new mode bits + m_modified |= MODE_MASK; + } + int getMode() { + switch (m_value & MODE_MASK) { + case 0x00003000: return(0); + case 0x00017900: return(1); + case 0x00057900: return(2); + case 0x00037A00: return(3); + case 0x00077A00: return(4); + case 0x0007A400: return(5); + case 0x00079400: return(6); + case 0x00078400: return(7); + default: return (-1); + } + } + bool isModeOff() { + return !(m_value & MODE_MASK); + } + bool isModeModified() { + return (m_modified & MODE_MASK); + } + + // Return the number of the Nyquist zone for the + // current receiver setting. + // 0 = indeterminate + // 1 = Nyquist zone I + // 2 = Nyquist zone II + // 3 = Nyquist zone III + int getNyquistZone() const; + + bool LBAfilter() const { return (!HBAinput() && (m_value & _30MHZ_MASK)); } + + bool LBLinput() const { return ((m_value & INPUT_SEL) == (LBL_EN | BANDSEL | VL_EN)); } + bool LBHinput() const { return ((m_value & INPUT_SEL) == (LBH_EN | BANDSEL | VL_EN)); } + bool HBAinput() const { return ((m_value & INPUT_SEL) == (HB_EN | VH_EN)); } + + // Set the raw control bytes of a RCU + // Each RCU has 4 bytes: + // mask meaning explanation + // 0x0000007F INPUT_DELAY Sample delay for the data from the RCU. + // 0x00000080 INPUT_ENABLE Enable RCU input + // + // 0x00000100 LBL-EN supply LBL antenna on (1) or off (0) + // 0x00000200 LBH-EN sypply LBH antenna on (1) or off (0) + // 0x00000400 HB-EN supply HB on (1) or off (0) + // 0x00000800 BANDSEL low band (1) or high band (0) + // 0x00001000 HB-SEL-0 HBA filter selection + // 0x00002000 HB-SEL-1 HBA filter selection + // Options : HBA-SEL-0 HBA-SEL-1 Function + // 0 0 210-270 MHz + // 0 1 170-230 MHz + // 1 0 110-190 MHz + // 1 1 all off + // 0x00004000 VL-EN low band supply on (1) or off (0) + // 0x00008000 VH-EN high band supply on (1) or off (0) + // + // 0x00010000 VDIG-EN ADC supply on (1) or off (0) + // 0x00020000 LB-SEL-0 LBA input selection + // 0x00040000 LB-SEL-1 HP filter selection + // Options : LB-SEL-0 LB-SEL-1 Function + // 0 0 10-90 MHz + 10 MHz HPF + // 0 1 30-80 MHz + 10 MHz HPF + // 1 0 10-90 MHz + 30 MHz HPF + // 1 1 30-80 MHz + 30 MHz HPF + // 0x00080000 ATT-CNT-4 on (1) is 1dB attenuation + // 0x00100000 ATT-CNT-3 on (1) is 2dB attenuation + // 0x00200000 ATT-CNT-2 on (1) is 4dB attenuation + // 0x00300000 ATT-CNT-1 on (1) is 8dB attenuation + // 0x00800000 ATT-CNT-0 on (1) is 16dB attenuation + // + // 0x01000000 PRSG pseudo random sequence generator on (1), off (0) + // 0x02000000 RESET on (1) hold board in reset + // 0x04000000 free used to be SPEC_INV, SI now in DIAG/Bypass + // 0x08000000 TBD reserved + // 0xF0000000 VERSION RCU version //PD + void setRaw(uint32 raw) { m_value = raw; m_modified = 0xFFFFFFFF; } + uint32 getRaw() const { return m_value; } + // set protocol part of the raw byte + void setProtocolRaw(uint32 raw) { + m_value = (m_value & RCU_HANDLER_MASK) | (raw & RCU_PROTOCOL_MASK); + m_modified = RCU_PROTOCOL_MASK; + } + + // Enable (true) or disable (false) pseudo random sequence generator. + void setPRSG(bool value) { + if (value) m_value |= PRSG_MASK; // set PRSG bit + else m_value &= ~PRSG_MASK; // clear PRSG bit + m_modified |= PRSG_MASK; + } + bool getPRSG() const { return (m_value & PRSG_MASK) >> (16 + 8); } + + // Enable (true) or disable (false) reset on RCU. + void setReset(bool value) { + if (value) m_value |= RESET_MASK; // set RESET bit + else m_value &= ~RESET_MASK; // clear RESET bit + m_modified |= RESET_MASK; + } + bool getReset() const { return (m_value & RESET_MASK) >> (17 + 8); } + + // Set attenuation. Valid values are 0..31 (5 bits). + void setAttenuation(uint8 value) { + // useful bits should be is in lower 5 bits + value &= 0x1F; + m_value &= ~ATT_MASK; // clear mode bits + // cast value to uint32 to allow << 11, set new mode bits + m_value |= (((uint32)value << (11 + 8)) & ATT_MASK); + m_modified |= ATT_MASK; + } + uint8 getAttenuation() const { return (m_value & ATT_MASK) >> (11 + 8); } + + // Set sample delay (true time delay). Valid values are 0..127 (7 bits) + void setDelay(uint8 value) { + m_value &= ~DELAY_MASK; + m_value |= (value & DELAY_MASK); + m_modified |= DELAY_MASK; + } + uint8 getDelay() const { return m_value & DELAY_MASK; } + + // Set rcu enable (0 = disable, 1 = enable) + void setEnable(uint8 value) { + if (value) m_value |= ENABLE_MASK; // set ENABLE bit + else m_value &= ~ENABLE_MASK; // clear ENABLE bit + m_modified |= ENABLE_MASK; + } + bool getEnable() const { return m_value & ENABLE_MASK; } + + // Set rcu version //PD + void setVersion(uint8 value) { + m_value &= ~VERSION_MASK; // clear VERSION bit + if (value) m_value |= ((value & 0x0F) << (20 + 8)); // set VERSION bits + m_modified |= VERSION_MASK; + } + uint8 getVersion() const { return (m_value & VERSION_MASK) >> (20 + 8); } + + // Get RCU handler and RCU protocol settings separately + bool isHandlerModified() { return (m_modified & RCU_HANDLER_MASK); } + bool isProtocolModified() { return (m_modified & RCU_PROTOCOL_MASK); } + bool isEnableModified() { return (m_modified & ENABLE_MASK); } + + // Reset value and modified mask. + void reset() { + m_value = 0x00000000; + m_modified = 0x00000000; + } + + // Return modification mask + uint32 getModified() const { return m_modified; } + + // Assignment + Control& operator=(const Control& rhs) { + if (this != &rhs) { // prevent self-assignment + m_value &= ~rhs.m_modified; // clear the modified bits + m_value |= (rhs.m_value & rhs.m_modified); // set the modified bits with new values + m_modified |= rhs.m_modified; // combine the masks + } + return *this; + } + + // Copy constructor + Control(const Control& rhs) { + this->reset(); // reset m_value and m_modified + *this = rhs; + } + + // print function for operator<< + ostream& print (ostream& os) const + { os << formatString("%08X", m_value); return (os); } + + private: + // constants used to set the appropriate mode + static const uint32 m_mode[]; + + // masks used to set/get bits + static const uint32 DELAY_MASK = 0x0000007F; + static const uint32 ENABLE_MASK = 0x00000080; + static const uint32 _30MHZ_MASK = 0x00040000; + static const uint32 MODE_MASK = 0x0007FF00; + static const uint32 ATT_MASK = 0x00F80000; + static const uint32 PRSG_MASK = 0x01000000; + static const uint32 RESET_MASK = 0x02000000; + static const uint32 SPECINV_MASK = 0x04000000; + static const uint32 VERSION_MASK = 0xF0000000; //PD + + static const uint32 LBL_EN = 0x00000100; + static const uint32 LBH_EN = 0x00000200; + static const uint32 HB_EN = 0x00000400; + static const uint32 BANDSEL = 0x00000800; + static const uint32 VL_EN = 0x00004000; + static const uint32 VH_EN = 0x00008000; + static const uint32 INPUT_SEL = 0x0000CF00; + + static const uint32 RCU_HANDLER_MASK = 0x000000FF; + static const uint32 RCU_PROTOCOL_MASK = 0xFFFFFF00; + + // ----- datamembers ----- + uint32 m_value; + uint32 m_modified; // mask of modified bits + }; // class Control + + /* get reference settings array */ + blitz::Array<Control, 1>& operator()(); public: - /*@{*/ - // marshalling methods - size_t getSize() const; - size_t pack (char* buffer) const; - size_t unpack(const char *buffer); - /*@}*/ + /*@{*/ + // marshalling methods + size_t getSize() const; + size_t pack (char* buffer) const; + size_t unpack(const char *buffer); + /*@}*/ private: - blitz::Array<Control, 1> m_registers; + blitz::Array<Control, 1> m_registers; }; -inline blitz::Array<RCUSettings::Control, 1>& RCUSettings::operator()() -{ - return (m_registers); +inline blitz::Array<RCUSettings::Control, 1>& RCUSettings::operator()() +{ + return (m_registers); } -inline ostream& operator<< (ostream& os, const RCUSettings::Control& aControl) +inline ostream& operator<< (ostream& os, const RCUSettings::Control& aControl) { - return (aControl.print(os)); + return (aControl.print(os)); } }; // namespace