First version of the MAX2871 shield library. Includes demo program with terminal for setting frequency on channel A.
Dependents: MAX2871-Synthesizer
Fork of MAX2871_Shield_MAXREFDES161 by
Diff: MAX2871.cpp
- Revision:
- 2:b47819dab536
- Parent:
- 1:40b397b31d13
diff -r 40b397b31d13 -r b47819dab536 MAX2871.cpp --- a/MAX2871.cpp Mon Jul 31 23:57:09 2017 +0000 +++ b/MAX2871.cpp Tue Jan 09 16:05:51 2018 +0000 @@ -39,9 +39,7 @@ //**************************************************************************** MAX2871::MAX2871(SPI &spiBus, PinName le): m_spiBus(spiBus), m_le(le, 1) -{ - f_reference = 50.0; - +{ reg0.all = 0x007d0000; reg1.all = 0x2000fff9; reg2.all = 0x00004042; @@ -49,7 +47,12 @@ reg4.all = 0x6180b23c; reg5.all = 0x00400005; reg6.all = 0x00000000; - update(); + + updateAll(); + + wait_ms(20); + + updateAll(); } //**************************************************************************** @@ -59,7 +62,7 @@ } //**************************************************************************** -void MAX2871::writeRegister(const uint32_t data) +void MAX2871::write(const uint32_t data) { m_le = 0; m_spiBus.write((0xFF000000 & data) >> 24); @@ -70,16 +73,27 @@ } //**************************************************************************** -void MAX2871::readRegister6() +void MAX2871::updateAll() +{ + write(reg5.all); + write(reg4.all); + write(reg3.all); + write(reg2.all); + write(reg1.all); + write(reg0.all); +} + +//**************************************************************************** +uint32_t MAX2871::readRegister6() { uint32_t raw, reg6read; reg5.bits.mux = 1; reg2.bits.mux = 0x4; - writeRegister(reg5.all); - writeRegister(reg2.all); + write(reg5.all); + write(reg2.all); - writeRegister(0x00000006); + write(0x00000006); m_spiBus.format(8,1); @@ -91,47 +105,139 @@ reg6read = (reg6read & 0xFFFE01FF) + (raw << 9); raw = m_spiBus.write(0x00); reg6read = (reg6read & 0xFFFFFE01) + (raw << 1); - raw = m_spiBus.write(0x00); - reg6read = (reg6read & 0xFFFFFFFE) + (raw >> 7); - reg6.all = reg6read; + m_spiBus.write(0x00); m_spiBus.format(8,0); -} - -//**************************************************************************** -void MAX2871::update() -{ - writeRegister(reg5.all); - writeRegister(reg4.all); - writeRegister(reg3.all); - writeRegister(reg2.all); - writeRegister(reg1.all); - writeRegister(reg0.all); + + return reg6read; } //**************************************************************************** -void MAX2871::frequency(const float freq) +void MAX2871::setRFOUTA(const double freq) { - uint32_t n,frac,m = 0; - float pll_coefficient; + uint32_t n,frac,m,diva = 0; + double pll_coefficient,fractional = 0; - float f_pfd = f_reference*(1+reg2.bits.dbr)/(reg2.bits.r*(1+reg2.bits.rdiv2)); + double f_pfd = getPFD(); - reg4.bits.diva = 0; - while(freq*powf(2,reg4.bits.diva) < 3000.0) + while(freq*powf(2,diva) < 3000.0) { - reg4.bits.diva = reg4.bits.diva + 1; + diva = diva + 1; } - pll_coefficient = freq*powf(2,reg4.bits.diva)/f_pfd; - + pll_coefficient = freq*powf(2,diva)/f_pfd; n = floor(pll_coefficient); - pll_coefficient = pll_coefficient - n; + fractional = pll_coefficient - n; m = 4000; - frac = floor(m*pll_coefficient); + frac = rint(m*fractional); reg0.bits.frac = frac; reg0.bits.n = n; reg1.bits.m = m; - update(); + reg4.bits.diva = diva; + + reg3.bits.mutedel = 1; + + updateAll(); + f_rfouta = f_pfd*(reg0.bits.n+1.0*reg0.bits.frac/reg1.bits.m)/powf(2,reg4.bits.diva); +} + +void MAX2871::setPFD(const double ref_in,const uint16_t rdiv) +{ + f_pfd = ref_in/rdiv; + + if(f_pfd > 32.0) + reg2.bits.lds = 1; + else reg2.bits.lds = 0; + + reg3.bits.cdiv = rint(f_pfd/0.10); + + reg2.bits.dbr = 0; + reg2.bits.rdiv2 = 0; + reg2.bits.r = rdiv; + + uint32_t bs = f_pfd*20; + + if (bs > 1023) + bs = 1023; + else if (bs < 1) + bs = 1; + + reg4.bits.bs = 0x03FF & bs; + reg4.bits.bs2 = 0x03 & (bs >> 8); + + updateAll(); } + +double MAX2871::readADC() +{ + reg5.bits.adcm = 0x4; + reg5.bits.adcs = 1; + write(reg5.all); + wait_us(100); + + reg6.all = readRegister6(); + + reg5.bits.adcm = 0; + reg5.bits.adcs = 0; + write(reg5.all); + + if((reg6.bits.vasa == 0) & (reg6.bits.adcv = 1)) + { + double volts = 0.315 + 0.0165*(double)reg6.bits.adc; + return volts; + } else + return -1; +} + +uint32_t MAX2871::readVCO() +{ + + reg6.all = readRegister6(); + + return reg6.bits.v; +} + +void MAX2871::powerOn(const bool pwr) +{ + reg2.bits.shdn = !pwr; + reg4.bits.sdldo = !pwr; + reg4.bits.sddiv = !pwr; + reg4.bits.sdref = !pwr; + reg4.bits.sdvco = !pwr; + reg5.bits.sdpll = !pwr; + + updateAll(); +} + +double MAX2871::getPFD() +{ + return f_pfd; +} + +double MAX2871::getRFOUTA() +{ + f_rfouta = f_pfd*(reg0.bits.n+1.0*reg0.bits.frac/reg1.bits.m)/powf(2,reg4.bits.diva); + return f_rfouta; +} + +double MAX2871::readTEMP() +{ + reg5.bits.adcm = 0x1; + reg5.bits.adcs = 1; + write(reg5.all); + wait_us(100); + + reg6.all = readRegister6(); + + reg5.bits.adcm = 0; + reg5.bits.adcs = 0; + write(reg5.all); + + if(reg6.bits.adcv == 1) + { + double degrees = 95 - 1.14*(double)reg6.bits.adc; + return degrees; + } else + return -1; +}