void EvrCML::setPattern(pattern p, const unsigned char *buf, epicsUInt32 blen) { // If we are given a length that is not a multiple of CML word size // then truncate. if(blen%mult){ printf("Given length %u is not a multiple of %u (CML word size).", blen, mult); blen-=blen%mult; printf("Truncating to %u\n", blen); } if(blen>lenPatternMax(p)) throw std::out_of_range("Pattern is too long"); epicsUInt32 val=0; for(epicsUInt32 i=0; i<blen; i++) { size_t cmlword = (i/mult); size_t cmlbit = (i%mult); size_t cpuword, cpubit; if(mult<32) { cpuword = cmlword; cpubit = 19 - cmlbit; } else { cpuword = 2*cmlword + (cmlbit<8 ? 0 : 1); cpubit = cmlbit<8 ? 7-cmlbit : 31-(cmlbit-8); } val|=(!!buf[i])<<cpubit; // cpubit is counting down. // write complete dword after the last bit is set if(cpubit==0) { shadowPattern[p][cpuword] = val; val=0; } } if(p==patternWaveform) shadowWaveformlength = blen/mult; // temporarly disable when changing multi dword patterns // to prevent output of incomplete patterns bool active=enabled(); if(active) enable(false); if(mode()==cmlModePattern) WRITE32(base, OutputCMLPatLength(N), shadowWaveformlength-1); syncPattern(p); if(active) enable(true); }
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); }