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 Central Applications - Mbed Code repo

Revision:
2:b47819dab536
Parent:
1:40b397b31d13
--- 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;
+}