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

Files at this revision

API Documentation at this revision

Comitter:
MI
Date:
Tue Jan 09 16:05:51 2018 +0000
Parent:
1:40b397b31d13
Commit message:
working through some additional features

Changed in this revision

MAX2871.cpp Show annotated file Show diff for this revision Revisions of this file
MAX2871.h Show annotated file Show diff for this revision Revisions of this file
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;
+}
diff -r 40b397b31d13 -r b47819dab536 MAX2871.h
--- a/MAX2871.h	Mon Jul 31 23:57:09 2017 +0000
+++ b/MAX2871.h	Tue Jan 09 16:05:51 2018 +0000
@@ -104,13 +104,26 @@
 class MAX2871
 {
 public:
-    ///Register 0 bits
+
+    //MAX2871 Registers
+    enum Registers_e
+    {
+        REG0          = 0x00,
+        REG1          = 0x01,
+        REG2          = 0x02,
+        REG3          = 0x03,
+        REG4          = 0x04,
+        REG5          = 0x05,
+        REG6          = 0x06
+    };
+    
+    //Register 0 bits
     union REG0_u
     {
-        ///Access all bits
+        //Access all bits
         uint32_t all;
         
-        ///Access individual bits
+        //Access individual bits
         struct BitField_s
         {
             uint32_t addr       : 3;
@@ -120,13 +133,13 @@
         }bits;
     };
     
-    ///Register 1 bits
+    //Register 1 bits
     union REG1_u
     {
-        ///Access all bits
+        //Access all bits
         uint32_t all;
         
-        ///Access individual bits
+        //Access individual bits
         struct BitField_s
         {
             uint32_t addr         : 3;
@@ -138,13 +151,13 @@
         }bits;
     };
     
-    ///Register 2 bits
+    //Register 2 bits
     union REG2_u
     {
-        ///Access all bits
+        //Access all bits
         uint32_t all;
         
-        ///Access individual bits
+        //Access individual bits
         struct BitField_s
         {
             uint32_t addr      : 3;
@@ -165,13 +178,13 @@
         }bits;
     };
     
-    ///Register 3 bits
+    //Register 3 bits
     union REG3_u
     {
-        ///Access all bits
+        //Access all bits
         uint32_t all;
         
-        ///Access individual bits
+        //Access individual bits
         struct BitField_s
         {
             uint32_t addr      : 3;
@@ -186,13 +199,13 @@
         }bits;
     };
     
-    ///Register 4 bits
+    //Register 4 bits
     union REG4_u
     {
-        ///Access all bits
+        //Access all bits
         uint32_t all;
         
-        ///Access individual bits
+        //Access individual bits
         struct BitField_s
         {
             uint32_t addr       : 3;
@@ -214,13 +227,13 @@
         }bits;
     };
     
-    ///Register 5 bits
+    //Register 5 bits
     union REG5_u
     {
-        ///Access all bits
+        //Access all bits
         uint32_t all;
         
-        ///Access individual bits
+        //Access individual bits
         struct BitField_s
         {
             uint32_t addr      : 3;
@@ -239,13 +252,13 @@
         }bits;
     };
     
-    ///Register 6 bits
+    //Register 6 bits
     union REG6_u
     {
-        ///Access all bits
+        //Access all bits
         uint32_t all;
         
-        ///Access individual bits
+        //Access individual bits
         struct BitField_s
         {
             uint32_t addr      : 3;
@@ -260,16 +273,6 @@
         }bits;
     };
     
-    REG0_u reg0;
-    REG1_u reg1;
-    REG2_u reg2;
-    REG3_u reg3;
-    REG4_u reg4;
-    REG5_u reg5;
-    REG6_u reg6;
-    
-    float f_reference;
-    
     ///@brief MAX2871 Constructor
     ///@param spiBus - Reference to spi interface
     ///@param le - Pin used for latch enable
@@ -278,37 +281,69 @@
     ///@brief MAX2871 Destructor
     ~MAX2871();
        
-    ///@brief Write given register.\n
+    ///@brief Writes raw 32-bit data pattern. The MAX2871 accepts 32-bit words at a time; 29 data bits and 3 address bits.
     ///
     ///On Entry:
-    ///@param[in] reg - Register to write
-    ///@param[in] data - Data to write 
+    ///@param[in] data - 32-bit word to write to the MAX2871. Bits[31:3] contain the register data, and Bits[2:0] contain the register address.
     ///
     ///@returns None
-    void writeRegister(const uint32_t data);
+    void write(const uint32_t data);
     
-    ///@brief Read Register 6 and update reg6 member.\n
+    ///@brief Read Register 6 and update reg6 member variable. The MAX2871 only has one readable register - Register 6.
+    ///
+    ///@returns 32-bit word whose lowest bits are '110' indicating register address 6.
+    uint32_t readRegister6();
+    
+    ///@brief Updates MAX2871 settings to achieve target output frequency on channel A.\n
+    ///
+    ///On Entry:
+    ///@param[in] freq - Frequency in MHz 
     ///
     ///@returns None
-    void readRegister6();
+    void setRFOUTA(const double freq);
     
-    ///@brief Update all registers.\n
+    ///@brief Provide frequency input to REF_IN pin.\n
+    ///
+    ///On Entry:
+    ///@param[in] ref_in - Frequency in MHz
     ///
     ///@returns None
-    void update();
+    void setPFD(const double ref_in, const uint16_t rdiv);
     
-    ///@brief Updates MAX2871 settings to achieve frequency output.\n
+    double getPFD();
+    
+    ///@brief Read ADC voltage.\n
     ///
     ///On Entry:
-    ///@param[in] freq - Frequency in MHz
     ///
-    ///@returns None
-    void frequency(const float freq);
+    ///@returns ADC reading in Volts   
+    double readADC();
+    
+    uint32_t readVCO();
+    
+    void powerOn(const bool pwr);
+    
+    double getRFOUTA();
+    
+    double readTEMP();
+    
+    void updateAll();
 
 private:
 
     SPI &m_spiBus;
     DigitalOut m_le;
+    
+    REG0_u reg0;
+    REG1_u reg1;
+    REG2_u reg2;
+    REG3_u reg3;
+    REG4_u reg4;
+    REG5_u reg5;
+    REG6_u reg6;
+    
+    double f_pfd;
+    double f_rfouta;
 };
  
 #endif /* _MAX2871_H_ */