MRMCML::MRMCML(const std::string& n, unsigned char i,EVRMRM& o, outkind k, formFactor f) :CML(n) ,mult(f==formFactor_CPCIFULL ? 40 : 20) // CML word length ,wordlen(f==formFactor_CPCIFULL ? 2 : 1)// # of 32-bit dwords used to store 1 CML word // 40 bits fit in 2 dwords, 20 bits fit in 1 ,base(o.base) ,N(i) ,owner(o) ,shadowEnable(0) ,shadowWaveformlength(0) ,kind(k) { epicsUInt32 val=READ32(base, OutputCMLEna(N)); val&=~OutputCMLEna_type_mask; switch(kind) { case typeCML: break; case typeTG203: val|=OutputCMLEna_type_203; break; case typeTG300: val|=OutputCMLEna_type_300; break; default: throw std::invalid_argument("Invalid CML kind"); } for(size_t i=0; i<NELEMENTS(shadowPattern); i++) { epicsUInt32 L = wordlen * (lenPatternMax((pattern)i)/mult); shadowPattern[i] = new epicsUInt32[L]; std::fill(shadowPattern[i], shadowPattern[i]+L, 0); } shadowEnable=val; }
void MRMCML::setRecyclePat(bool s) { if(s) shadowEnable |= OutputCMLEna_cycl; else shadowEnable &= ~OutputCMLEna_cycl; WRITE32(base, OutputCMLEna(N), shadowEnable); }
void MRMCML::setPolarityInvert(bool s) { if(s) shadowEnable |= OutputCMLEna_ftrg; else shadowEnable &= ~OutputCMLEna_ftrg; WRITE32(base, OutputCMLEna(N), shadowEnable); }
void MRMCML::power(bool s) { if(!s) shadowEnable |= OutputCMLEna_pow; else shadowEnable &= ~OutputCMLEna_pow; WRITE32(base, OutputCMLEna(N), shadowEnable); }
void MRMCML::reset(bool s) { if(s) shadowEnable |= OutputCMLEna_rst; else shadowEnable &= ~OutputCMLEna_rst; WRITE32(base, OutputCMLEna(N), shadowEnable); }
void MRMCML::enable(bool s) { if(s) shadowEnable |= OutputCMLEna_ena; else shadowEnable &= ~OutputCMLEna_ena; WRITE32(base, OutputCMLEna(N), shadowEnable); }
void MRMCML::setCountInit (epicsUInt32 v) { v = std::min(v, 65535u); v <<= OutputCMLEna_ftrig_shft; shadowEnable &= ~OutputCMLEna_ftrig_mask; shadowEnable |= v; WRITE32(base, OutputCMLEna(N), shadowEnable); }
void EvrCML::setCountInit (epicsUInt32 v) { if(v>=65535) throw std::out_of_range("Invalid CML freq. count"); v <<= OutputCMLEna_ftrig_shft; shadowEnable &= ~OutputCMLEna_ftrig_mask; shadowEnable |= v; WRITE32(base, OutputCMLEna(N), shadowEnable); }
void MRMCML::setMode(cmlMode m) { epicsUInt32 mask=0; switch(m) { case cmlModeOrig: mask |= OutputCMLEna_mode_orig; break; case cmlModeFreq: mask |= OutputCMLEna_mode_freq; break; case cmlModePattern: mask |= OutputCMLEna_mode_patt; break; default: throw std::out_of_range("Invalid CML Mode"); } bool wasenabled = enabled(); shadowEnable &= ~OutputCMLEna_ena; // disable while syncing shadowEnable &= ~OutputCMLEna_mode_mask; shadowEnable |= mask; WRITE32(base, OutputCMLEna(N), shadowEnable); switch(m) { case cmlModeOrig: WRITE32(base, OutputCMLPatLength(N), 0); syncPattern(patternFall); syncPattern(patternHigh); syncPattern(patternLow); syncPattern(patternRise); break; case cmlModePattern: WRITE32(base, OutputCMLPatLength(N), shadowWaveformlength-1); syncPattern(patternWaveform); break; default: break; } if(wasenabled) shadowEnable |= OutputCMLEna_ena; // enable after syncing WRITE32(base, OutputCMLEna(N), shadowEnable); }
EvrCML::EvrCML(const std::string& n, size_t i, EVRMRM& o, outkind k, formFactor f) :mrf::ObjectInst<EvrCML>(n) ,base(o.base) ,N(i) ,owner(o) ,shadowEnable(0) ,shadowWaveformlength(0) ,kind(k) { epicsUInt32 version = o.version(); if(f==formFactor_CPCIFULL || version > 200){ mult = 40; wordlen = 2; }else{ mult = 20; wordlen = 1; } epicsUInt32 val=READ32(base, OutputCMLEna(N)); val&=~OutputCMLEna_type_mask; switch(kind) { case typeCML: break; case typeTG203: val|=OutputCMLEna_type_203; break; case typeTG300: val|=OutputCMLEna_type_300; break; default: throw std::invalid_argument("Invalid CML kind"); } for(size_t i=0; i<NELEMENTS(shadowPattern); i++) { epicsUInt32 L = wordlen * (lenPatternMax((pattern)i)/mult); shadowPattern[i] = new epicsUInt32[L]; std::fill(shadowPattern[i], shadowPattern[i]+L, 0); } shadowEnable=val; }