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

Committer:
MI
Date:
Tue Jan 09 16:05:51 2018 +0000
Revision:
2:b47819dab536
Parent:
1:40b397b31d13
working through some additional features

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MI 0:9f09f1b58389 1 /*******************************************************************************
MI 0:9f09f1b58389 2 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
MI 0:9f09f1b58389 3 *
MI 0:9f09f1b58389 4 * Permission is hereby granted, free of charge, to any person obtaining a
MI 0:9f09f1b58389 5 * copy of this software and associated documentation files (the "Software"),
MI 0:9f09f1b58389 6 * to deal in the Software without restriction, including without limitation
MI 0:9f09f1b58389 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
MI 0:9f09f1b58389 8 * and/or sell copies of the Software, and to permit persons to whom the
MI 0:9f09f1b58389 9 * Software is furnished to do so, subject to the following conditions:
MI 0:9f09f1b58389 10 *
MI 0:9f09f1b58389 11 * The above copyright notice and this permission notice shall be included
MI 0:9f09f1b58389 12 * in all copies or substantial portions of the Software.
MI 0:9f09f1b58389 13 *
MI 0:9f09f1b58389 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
MI 0:9f09f1b58389 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MI 0:9f09f1b58389 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
MI 0:9f09f1b58389 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
MI 0:9f09f1b58389 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
MI 0:9f09f1b58389 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
MI 0:9f09f1b58389 20 * OTHER DEALINGS IN THE SOFTWARE.
MI 0:9f09f1b58389 21 *
MI 0:9f09f1b58389 22 * Except as contained in this notice, the name of Maxim Integrated
MI 0:9f09f1b58389 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
MI 0:9f09f1b58389 24 * Products, Inc. Branding Policy.
MI 0:9f09f1b58389 25 *
MI 0:9f09f1b58389 26 * The mere transfer of this software does not imply any licenses
MI 0:9f09f1b58389 27 * of trade secrets, proprietary technology, copyrights, patents,
MI 0:9f09f1b58389 28 * trademarks, maskwork rights, or any other form of intellectual
MI 0:9f09f1b58389 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
MI 0:9f09f1b58389 30 * ownership rights.
MI 0:9f09f1b58389 31 *******************************************************************************
MI 0:9f09f1b58389 32 */
MI 0:9f09f1b58389 33
MI 0:9f09f1b58389 34
MI 0:9f09f1b58389 35 #include "MAX2871.h"
MI 0:9f09f1b58389 36 #include <math.h>
MI 0:9f09f1b58389 37 #include <stdio.h>
MI 0:9f09f1b58389 38
MI 0:9f09f1b58389 39 //****************************************************************************
MI 0:9f09f1b58389 40 MAX2871::MAX2871(SPI &spiBus, PinName le):
MI 0:9f09f1b58389 41 m_spiBus(spiBus), m_le(le, 1)
MI 2:b47819dab536 42 {
MI 0:9f09f1b58389 43 reg0.all = 0x007d0000;
MI 0:9f09f1b58389 44 reg1.all = 0x2000fff9;
MI 0:9f09f1b58389 45 reg2.all = 0x00004042;
MI 0:9f09f1b58389 46 reg3.all = 0x0000000b;
MI 0:9f09f1b58389 47 reg4.all = 0x6180b23c;
MI 0:9f09f1b58389 48 reg5.all = 0x00400005;
MI 0:9f09f1b58389 49 reg6.all = 0x00000000;
MI 2:b47819dab536 50
MI 2:b47819dab536 51 updateAll();
MI 2:b47819dab536 52
MI 2:b47819dab536 53 wait_ms(20);
MI 2:b47819dab536 54
MI 2:b47819dab536 55 updateAll();
MI 0:9f09f1b58389 56 }
MI 0:9f09f1b58389 57
MI 0:9f09f1b58389 58 //****************************************************************************
MI 0:9f09f1b58389 59 MAX2871::~MAX2871()
MI 0:9f09f1b58389 60 {
MI 0:9f09f1b58389 61 //empty block
MI 0:9f09f1b58389 62 }
MI 0:9f09f1b58389 63
MI 0:9f09f1b58389 64 //****************************************************************************
MI 2:b47819dab536 65 void MAX2871::write(const uint32_t data)
MI 0:9f09f1b58389 66 {
MI 0:9f09f1b58389 67 m_le = 0;
MI 0:9f09f1b58389 68 m_spiBus.write((0xFF000000 & data) >> 24);
MI 0:9f09f1b58389 69 m_spiBus.write((0x00FF0000 & data) >> 16);
MI 0:9f09f1b58389 70 m_spiBus.write((0x0000FF00 & data) >> 8);
MI 0:9f09f1b58389 71 m_spiBus.write( 0x000000FF & data);
MI 0:9f09f1b58389 72 m_le = 1;
MI 0:9f09f1b58389 73 }
MI 0:9f09f1b58389 74
MI 0:9f09f1b58389 75 //****************************************************************************
MI 2:b47819dab536 76 void MAX2871::updateAll()
MI 2:b47819dab536 77 {
MI 2:b47819dab536 78 write(reg5.all);
MI 2:b47819dab536 79 write(reg4.all);
MI 2:b47819dab536 80 write(reg3.all);
MI 2:b47819dab536 81 write(reg2.all);
MI 2:b47819dab536 82 write(reg1.all);
MI 2:b47819dab536 83 write(reg0.all);
MI 2:b47819dab536 84 }
MI 2:b47819dab536 85
MI 2:b47819dab536 86 //****************************************************************************
MI 2:b47819dab536 87 uint32_t MAX2871::readRegister6()
MI 0:9f09f1b58389 88 {
MI 0:9f09f1b58389 89 uint32_t raw, reg6read;
MI 0:9f09f1b58389 90
MI 0:9f09f1b58389 91 reg5.bits.mux = 1;
MI 0:9f09f1b58389 92 reg2.bits.mux = 0x4;
MI 2:b47819dab536 93 write(reg5.all);
MI 2:b47819dab536 94 write(reg2.all);
MI 0:9f09f1b58389 95
MI 2:b47819dab536 96 write(0x00000006);
MI 0:9f09f1b58389 97
MI 0:9f09f1b58389 98 m_spiBus.format(8,1);
MI 0:9f09f1b58389 99
MI 0:9f09f1b58389 100 raw = m_spiBus.write(0x00);
MI 0:9f09f1b58389 101 reg6read = (reg6read & 0x01FFFFF) + (raw << 25);
MI 0:9f09f1b58389 102 raw = m_spiBus.write(0x00);
MI 0:9f09f1b58389 103 reg6read = (reg6read & 0xFE01FFFF) + (raw << 17);
MI 0:9f09f1b58389 104 raw = m_spiBus.write(0x00);
MI 0:9f09f1b58389 105 reg6read = (reg6read & 0xFFFE01FF) + (raw << 9);
MI 0:9f09f1b58389 106 raw = m_spiBus.write(0x00);
MI 0:9f09f1b58389 107 reg6read = (reg6read & 0xFFFFFE01) + (raw << 1);
MI 2:b47819dab536 108 m_spiBus.write(0x00);
MI 0:9f09f1b58389 109
MI 0:9f09f1b58389 110 m_spiBus.format(8,0);
MI 2:b47819dab536 111
MI 2:b47819dab536 112 return reg6read;
MI 0:9f09f1b58389 113 }
MI 0:9f09f1b58389 114
MI 0:9f09f1b58389 115 //****************************************************************************
MI 2:b47819dab536 116 void MAX2871::setRFOUTA(const double freq)
MI 0:9f09f1b58389 117 {
MI 2:b47819dab536 118 uint32_t n,frac,m,diva = 0;
MI 2:b47819dab536 119 double pll_coefficient,fractional = 0;
MI 0:9f09f1b58389 120
MI 2:b47819dab536 121 double f_pfd = getPFD();
MI 0:9f09f1b58389 122
MI 2:b47819dab536 123 while(freq*powf(2,diva) < 3000.0)
MI 0:9f09f1b58389 124 {
MI 2:b47819dab536 125 diva = diva + 1;
MI 0:9f09f1b58389 126 }
MI 2:b47819dab536 127 pll_coefficient = freq*powf(2,diva)/f_pfd;
MI 0:9f09f1b58389 128 n = floor(pll_coefficient);
MI 0:9f09f1b58389 129
MI 2:b47819dab536 130 fractional = pll_coefficient - n;
MI 1:40b397b31d13 131 m = 4000;
MI 2:b47819dab536 132 frac = rint(m*fractional);
MI 0:9f09f1b58389 133
MI 0:9f09f1b58389 134 reg0.bits.frac = frac;
MI 0:9f09f1b58389 135 reg0.bits.n = n;
MI 0:9f09f1b58389 136 reg1.bits.m = m;
MI 2:b47819dab536 137 reg4.bits.diva = diva;
MI 2:b47819dab536 138
MI 2:b47819dab536 139 reg3.bits.mutedel = 1;
MI 2:b47819dab536 140
MI 2:b47819dab536 141 updateAll();
MI 2:b47819dab536 142 f_rfouta = f_pfd*(reg0.bits.n+1.0*reg0.bits.frac/reg1.bits.m)/powf(2,reg4.bits.diva);
MI 2:b47819dab536 143 }
MI 2:b47819dab536 144
MI 2:b47819dab536 145 void MAX2871::setPFD(const double ref_in,const uint16_t rdiv)
MI 2:b47819dab536 146 {
MI 2:b47819dab536 147 f_pfd = ref_in/rdiv;
MI 2:b47819dab536 148
MI 2:b47819dab536 149 if(f_pfd > 32.0)
MI 2:b47819dab536 150 reg2.bits.lds = 1;
MI 2:b47819dab536 151 else reg2.bits.lds = 0;
MI 2:b47819dab536 152
MI 2:b47819dab536 153 reg3.bits.cdiv = rint(f_pfd/0.10);
MI 2:b47819dab536 154
MI 2:b47819dab536 155 reg2.bits.dbr = 0;
MI 2:b47819dab536 156 reg2.bits.rdiv2 = 0;
MI 2:b47819dab536 157 reg2.bits.r = rdiv;
MI 2:b47819dab536 158
MI 2:b47819dab536 159 uint32_t bs = f_pfd*20;
MI 2:b47819dab536 160
MI 2:b47819dab536 161 if (bs > 1023)
MI 2:b47819dab536 162 bs = 1023;
MI 2:b47819dab536 163 else if (bs < 1)
MI 2:b47819dab536 164 bs = 1;
MI 2:b47819dab536 165
MI 2:b47819dab536 166 reg4.bits.bs = 0x03FF & bs;
MI 2:b47819dab536 167 reg4.bits.bs2 = 0x03 & (bs >> 8);
MI 2:b47819dab536 168
MI 2:b47819dab536 169 updateAll();
MI 0:9f09f1b58389 170 }
MI 2:b47819dab536 171
MI 2:b47819dab536 172 double MAX2871::readADC()
MI 2:b47819dab536 173 {
MI 2:b47819dab536 174 reg5.bits.adcm = 0x4;
MI 2:b47819dab536 175 reg5.bits.adcs = 1;
MI 2:b47819dab536 176 write(reg5.all);
MI 2:b47819dab536 177 wait_us(100);
MI 2:b47819dab536 178
MI 2:b47819dab536 179 reg6.all = readRegister6();
MI 2:b47819dab536 180
MI 2:b47819dab536 181 reg5.bits.adcm = 0;
MI 2:b47819dab536 182 reg5.bits.adcs = 0;
MI 2:b47819dab536 183 write(reg5.all);
MI 2:b47819dab536 184
MI 2:b47819dab536 185 if((reg6.bits.vasa == 0) & (reg6.bits.adcv = 1))
MI 2:b47819dab536 186 {
MI 2:b47819dab536 187 double volts = 0.315 + 0.0165*(double)reg6.bits.adc;
MI 2:b47819dab536 188 return volts;
MI 2:b47819dab536 189 } else
MI 2:b47819dab536 190 return -1;
MI 2:b47819dab536 191 }
MI 2:b47819dab536 192
MI 2:b47819dab536 193 uint32_t MAX2871::readVCO()
MI 2:b47819dab536 194 {
MI 2:b47819dab536 195
MI 2:b47819dab536 196 reg6.all = readRegister6();
MI 2:b47819dab536 197
MI 2:b47819dab536 198 return reg6.bits.v;
MI 2:b47819dab536 199 }
MI 2:b47819dab536 200
MI 2:b47819dab536 201 void MAX2871::powerOn(const bool pwr)
MI 2:b47819dab536 202 {
MI 2:b47819dab536 203 reg2.bits.shdn = !pwr;
MI 2:b47819dab536 204 reg4.bits.sdldo = !pwr;
MI 2:b47819dab536 205 reg4.bits.sddiv = !pwr;
MI 2:b47819dab536 206 reg4.bits.sdref = !pwr;
MI 2:b47819dab536 207 reg4.bits.sdvco = !pwr;
MI 2:b47819dab536 208 reg5.bits.sdpll = !pwr;
MI 2:b47819dab536 209
MI 2:b47819dab536 210 updateAll();
MI 2:b47819dab536 211 }
MI 2:b47819dab536 212
MI 2:b47819dab536 213 double MAX2871::getPFD()
MI 2:b47819dab536 214 {
MI 2:b47819dab536 215 return f_pfd;
MI 2:b47819dab536 216 }
MI 2:b47819dab536 217
MI 2:b47819dab536 218 double MAX2871::getRFOUTA()
MI 2:b47819dab536 219 {
MI 2:b47819dab536 220 f_rfouta = f_pfd*(reg0.bits.n+1.0*reg0.bits.frac/reg1.bits.m)/powf(2,reg4.bits.diva);
MI 2:b47819dab536 221 return f_rfouta;
MI 2:b47819dab536 222 }
MI 2:b47819dab536 223
MI 2:b47819dab536 224 double MAX2871::readTEMP()
MI 2:b47819dab536 225 {
MI 2:b47819dab536 226 reg5.bits.adcm = 0x1;
MI 2:b47819dab536 227 reg5.bits.adcs = 1;
MI 2:b47819dab536 228 write(reg5.all);
MI 2:b47819dab536 229 wait_us(100);
MI 2:b47819dab536 230
MI 2:b47819dab536 231 reg6.all = readRegister6();
MI 2:b47819dab536 232
MI 2:b47819dab536 233 reg5.bits.adcm = 0;
MI 2:b47819dab536 234 reg5.bits.adcs = 0;
MI 2:b47819dab536 235 write(reg5.all);
MI 2:b47819dab536 236
MI 2:b47819dab536 237 if(reg6.bits.adcv == 1)
MI 2:b47819dab536 238 {
MI 2:b47819dab536 239 double degrees = 95 - 1.14*(double)reg6.bits.adc;
MI 2:b47819dab536 240 return degrees;
MI 2:b47819dab536 241 } else
MI 2:b47819dab536 242 return -1;
MI 2:b47819dab536 243 }