Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

# ad9854.c

Go to the documentation of this file.

    00001 /*! \file ad9854.c \brief Analog Devices AD9854 Digital Synthesizer Driver. */
    00002 //*****************************************************************************
    00003 //
    00004 // File Name    : 'ad9854.c'
    00005 // Title        : Analog Devices AD9854 Digital Synthesizer Driver
    00006 // Author       : Pascal Stang - Copyright (C) 2004
    00007 // Created      : 2004.05.05
    00008 // Revised      : 2004.07.12
    00009 // Version      : 0.1
    00010 // Target MCU   : ARM processors
    00011 // Editor Tabs  : 4
    00012 //
    00013 // NOTE: This code is currently below version 1.0, and therefore is considered
    00014 // to be lacking in some functionality or documentation, or may not be fully
    00015 // tested.  Nonetheless, you can expect most functions to work.
    00016 //
    00017 // This code is distributed under the GNU Public License
    00018 //      which can be found at http://www.gnu.org/licenses/gpl.txt
    00019 //
    00020 //*****************************************************************************
    00021
    00022 #include "lpc2000.h"
    00023
    00024 #include "global.h"
    00025 #include "timer.h"
    00026 #include "membus.h"
    00027 #include "rprintf.h"
    00028 #include "ad9854.h"
    00029
    00030 // global variables
    00031 int Ad9854RefClkMult;
    00032
    00033
    00034 void ad9854Write(unsigned int addr, unsigned char data)
    00035 {
    00036     ((u16*)AD9854_REG_BASE)[addr] = data;
    00037 }
    00038
    00039 unsigned char ad9854Read(unsigned int addr)
    00040 {
    00041     return ((u16*)AD9854_REG_BASE)[addr];
    00042 }
    00043
    00044 void ad9854Init(void)
    00045 {
    00046     //membusInit();
    00047
    00048 /*  // reset device
    00049     IOSET = AD9854_RESET;
    00050     IODIR |= AD9854_RESET;
    00051     delay(10000);
    00052     IOCLR = AD9854_RESET;
    00053 */
    00054     // setup IO Update pin
    00055     ad9854SetupIOUpdate(0);
    00056
    00057     // initialize variables
    00058     Ad9854RefClkMult = 1;
    00059 }
    00060
    00061 void ad9854SetupIOUpdate(int state)
    00062 {
    00063     // clear IO Update pin
    00064 //  IOCLR = AD9854_IO_UPDATE;
    00065 /*
    00066     if(state)
    00067         // set IO update line to output
    00068         IODIR |= AD9854_IO_UPDATE;
    00069     else
    00070         // set IO update line to input
    00071         IODIR &= ~AD9854_IO_UPDATE;
    00072 */
    00073 }
    00074
    00075 void ad9854ClockIOUpdate(void)
    00076 {
    00077     // assert IO Update line
    00078 //  IOSET = AD9854_IO_UPDATE;
    00079     // wait
    00080     asm volatile ("nop\r\n nop\r\n");
    00081     // clear IO Update line
    00082 //  IOCLR = AD9854_IO_UPDATE;
    00083 }
    00084
    00085 void ad9854WritePhase1(u16 phase)
    00086 {
    00087     ad9854Write(AD9854_REG_PHASE1L, phase);
    00088     ad9854Write(AD9854_REG_PHASE1H, phase>>8);
    00089 }
    00090
    00091 void ad9854WritePhase2(u16 phase)
    00092 {
    00093     ad9854Write(AD9854_REG_PHASE2L, phase);
    00094     ad9854Write(AD9854_REG_PHASE2H, phase>>8);
    00095 }
    00096
    00097 void ad9854WriteFreq1(u64 freq)
    00098 {
    00099     ad9854Write(AD9854_REG_FREQ10, freq);
    00100     ad9854Write(AD9854_REG_FREQ11, freq>>8);
    00101     ad9854Write(AD9854_REG_FREQ12, freq>>16);
    00102     ad9854Write(AD9854_REG_FREQ13, freq>>24);
    00103     ad9854Write(AD9854_REG_FREQ14, freq>>32);
    00104     ad9854Write(AD9854_REG_FREQ15, freq>>40);
    00105 }
    00106
    00107 void ad9854WriteFreq2(u64 freq)
    00108 {
    00109     ad9854Write(AD9854_REG_FREQ20, freq);
    00110     ad9854Write(AD9854_REG_FREQ21, freq>>8);
    00111     ad9854Write(AD9854_REG_FREQ22, freq>>16);
    00112     ad9854Write(AD9854_REG_FREQ23, freq>>24);
    00113     ad9854Write(AD9854_REG_FREQ24, freq>>32);
    00114     ad9854Write(AD9854_REG_FREQ25, freq>>40);
    00115 }
    00116
    00117 void ad9854WriteDeltaFreq(u64 freq)
    00118 {
    00119     ad9854Write(AD9854_REG_DELTA0, freq);
    00120     ad9854Write(AD9854_REG_DELTA1, freq>>8);
    00121     ad9854Write(AD9854_REG_DELTA2, freq>>16);
    00122     ad9854Write(AD9854_REG_DELTA3, freq>>24);
    00123     ad9854Write(AD9854_REG_DELTA4, freq>>32);
    00124     ad9854Write(AD9854_REG_DELTA5, freq>>48);
    00125 }
    00126
    00127 void ad9854WriteUpdateClock(u32 updclock)
    00128 {
    00129     ad9854Write(AD9854_REG_UPDCLOCK0, updclock);
    00130     ad9854Write(AD9854_REG_UPDCLOCK1, updclock>>8);
    00131     ad9854Write(AD9854_REG_UPDCLOCK2, updclock>>16);
    00132     ad9854Write(AD9854_REG_UPDCLOCK3, updclock>>24);
    00133 }
    00134
    00135 void ad9854WriteRampRateClock(u32 rampclock)
    00136 {
    00137     ad9854Write(AD9854_REG_RAMPCLOCK0, rampclock);
    00138     ad9854Write(AD9854_REG_RAMPCLOCK1, rampclock>>8);
    00139     ad9854Write(AD9854_REG_RAMPCLOCK2, rampclock>>16);
    00140 }
    00141
    00142 void ad9854WriteControlReg(u32 cr)
    00143 {
    00144     ad9854Write(AD9854_REG_CTRL0, cr);
    00145     ad9854Write(AD9854_REG_CTRL1, cr>>8);
    00146     ad9854Write(AD9854_REG_CTRL2, cr>>16);
    00147     ad9854Write(AD9854_REG_CTRL3, cr>>24);
    00148 }
    00149
    00150 void ad9854WriteAmplitudeI(u16 ampi)
    00151 {
    00152     ad9854Write(AD9854_REG_AMPLIL, ampi);
    00153     ad9854Write(AD9854_REG_AMPLIH, ampi>>8);
    00154 }
    00155
    00156 void ad9854WriteAmplitudeQ(u16 ampq)
    00157 {
    00158     ad9854Write(AD9854_REG_AMPLQL, ampq);
    00159     ad9854Write(AD9854_REG_AMPLQH, ampq>>8);
    00160 }
    00161
    00162 void ad9854WriteOSKeyRampRate(u16 ramprate)
    00163 {
    00164     ad9854Write(AD9854_REG_OSKEYRAMP, ramprate);
    00165 }
    00166
    00167 void ad9854WriteQDAC(u16 qdac)
    00168 {
    00169     ad9854Write(AD9854_REG_QDACL, qdac);
    00170     ad9854Write(AD9854_REG_QDACH, qdac>>8);
    00171 }
    00172
    00173 u32 ad9854ReadControlReg(void)
    00174 {
    00175     u32 cr=0;
    00176     cr  = (ad9854Read(AD9854_REG_CTRL0) & 0x000000FF);
    00177     cr |= (ad9854Read(AD9854_REG_CTRL1) & 0x000000FF)<<8;
    00178     cr |= (ad9854Read(AD9854_REG_CTRL2) & 0x000000FF)<<16;
    00179     cr |= (ad9854Read(AD9854_REG_CTRL3) & 0x000000FF)<<24;
    00180     return cr;
    00181 }
    00182
    00183 void ad9854ControlClear(u32 cr_clear)
    00184 {
    00185     u32 cr;
    00186     // read in control register
    00187     cr = ad9854ReadControlReg();
    00188     // clear bits
    00189     cr &= ~cr_clear;
    00190     // write control register
    00191     ad9854WriteControlReg(cr);
    00192 }
    00193
    00194 void ad9854ControlSet(u32 cr_set)
    00195 {
    00196     u32 cr;
    00197     // read in control register
    00198     cr = ad9854ReadControlReg();
    00199     // clear bits
    00200     cr |= cr_set;
    00201     // write control register
    00202     ad9854WriteControlReg(cr);
    00203 }
    00204
    00205 void ad9854SetMode(int mode)
    00206 {
    00207     u32 cr;
    00208     // read in control register
    00209     cr = ad9854ReadControlReg();
    00210     // set mode bits
    00211     cr &= ~AD9854_MODE_MASK;
    00212     cr |= (mode<<9) & AD9854_MODE_MASK;
    00213     // write control register
    00214     ad9854WriteControlReg(cr);
    00215 }
    00216
    00217 void ad9854SetPLL(int enabled, int mult)
    00218 {
    00219     u32 cr;
    00220     // read in control register
    00221     cr = ad9854ReadControlReg();
    00222     // set PLL state
    00223     if(enabled)
    00224     {
    00225         cr &= ~AD9854_PLL_BYPASS;
    00226         // set local state reference
    00227         Ad9854RefClkMult = mult;
    00228     }
    00229     else
    00230     {
    00231         cr |= AD9854_PLL_BYPASS;
    00232         // set local state reference
    00233         Ad9854RefClkMult = 1;
    00234     }
    00235     // set PLL multiplication ratio
    00236     cr &= ~AD9854_PLL_MULT_MASK;
    00237     cr |= (mult<<16) & AD9854_PLL_MULT_MASK;
    00238     // write control register
    00239     ad9854WriteControlReg(cr);
    00240 }
    00241
    00242 void ad9854SetFreq1(u32 freqHz)
    00243 {
    00244     u64 ftw;
    00245     // FTW = (Desired Output Frequency × 2^N)/SYSCLK
    00246     // where N = 48 bits
    00247
    00248     // split up the 2^N multiplication to avoid overflow/underflow
    00249     if(freqHz < 0x1000)
    00250     {
    00251         ftw = (((u64)freqHz<<33)/(AD9854_REFCLK_FREQ*Ad9854RefClkMult))<<15;
    00252     }
    00253     else if(freqHz < 0x10000)
    00254     {
    00255         ftw = (((u64)freqHz<<32)/(AD9854_REFCLK_FREQ*Ad9854RefClkMult))<<16;
    00256     }
    00257     else if(freqHz < 0x1000000)
    00258     {
    00259         ftw = (((u64)freqHz<<32)/(AD9854_REFCLK_FREQ*Ad9854RefClkMult))<<16;
    00260         //ftw = (((u64)freqHz<<30)/(AD9854_REFCLK_FREQ*Ad9854RefClkMult))<<18;
    00261     }
    00262     else
    00263     {
    00264         ftw = (((u64)freqHz<<32)/(AD9854_REFCLK_FREQ*Ad9854RefClkMult))<<16;
    00265         //ftw = (((u64)freqHz<<20)/(AD9854_REFCLK_FREQ*Ad9854RefClkMult))<<28;
    00266     }
    00267     ad9854WriteFreq1(ftw);
    00268 }
    00269
    00270 void ad9854SetUpdateClock(u32 updclockHz)
    00271 {
    00272     u32 updclock;
    00273
    00274     if(updclockHz)
    00275     {
    00276         // use internal update clock
    00277         // Update period = (N+1) × (SYSTEM CLOCK PERIOD × 2)
    00278         // Update freq = REFCLK_FREQ/(2*(N+1))
    00279         // N = ((REFCLK_FREQ*Ad9854RefClkMult)/(2*UpdateHz))-1
    00280         updclock = ((AD9854_REFCLK_FREQ*Ad9854RefClkMult)/(2*updclockHz))-1;
    00281
    00282         // turn off internal update
    00283         ad9854ControlClear(AD9854_INT_IO_UPDATE);
    00284         // write update counter register
    00285         ad9854WriteUpdateClock(updclock);
    00286         // turn on internal update
    00287         ad9854ControlSet(AD9854_INT_IO_UPDATE);
    00288         // manually clock update pin
    00289         ad9854SetupIOUpdate(1);
    00290         ad9854ClockIOUpdate();
    00291         ad9854SetupIOUpdate(0);
    00292     }
    00293     else
    00294     {
    00295         // turn off internal update
    00296         ad9854ControlClear(AD9854_INT_IO_UPDATE);
    00297         // use external update clock
    00298         ad9854SetupIOUpdate(0);
    00299     }
    00300
    00301 }
    00302
    00303 void ad9854ShowRegisters(void)
    00304 {
    00305     // read and print all registers
    00306
    00307     rprintfStr("Phase1      :         0x");
    00308     rprintfu08(ad9854Read(AD9854_REG_PHASE1H));
    00309     rprintfu08(ad9854Read(AD9854_REG_PHASE1L));
    00310     rprintfCRLF();
    00311
    00312     rprintfStr("Phase2      :         0x");
    00313     rprintfu08(ad9854Read(AD9854_REG_PHASE2H));
    00314     rprintfu08(ad9854Read(AD9854_REG_PHASE2L));
    00315     rprintfCRLF();
    00316
    00317     rprintfStr("Freq1       : 0x");
    00318     rprintfu08(ad9854Read(AD9854_REG_FREQ15));
    00319     rprintfu08(ad9854Read(AD9854_REG_FREQ14));
    00320     rprintfu08(ad9854Read(AD9854_REG_FREQ13));
    00321     rprintfu08(ad9854Read(AD9854_REG_FREQ12));
    00322     rprintfu08(ad9854Read(AD9854_REG_FREQ11));
    00323     rprintfu08(ad9854Read(AD9854_REG_FREQ10));
    00324     rprintfCRLF();
    00325
    00326     rprintfStr("Freq2       : 0x");
    00327     rprintfu08(ad9854Read(AD9854_REG_FREQ25));
    00328     rprintfu08(ad9854Read(AD9854_REG_FREQ24));
    00329     rprintfu08(ad9854Read(AD9854_REG_FREQ23));
    00330     rprintfu08(ad9854Read(AD9854_REG_FREQ22));
    00331     rprintfu08(ad9854Read(AD9854_REG_FREQ21));
    00332     rprintfu08(ad9854Read(AD9854_REG_FREQ20));
    00333     rprintfCRLF();
    00334
    00335     rprintfStr("DeltaFreq   : 0x");
    00336     rprintfu08(ad9854Read(AD9854_REG_DELTA5));
    00337     rprintfu08(ad9854Read(AD9854_REG_DELTA4));
    00338     rprintfu08(ad9854Read(AD9854_REG_DELTA3));
    00339     rprintfu08(ad9854Read(AD9854_REG_DELTA2));
    00340     rprintfu08(ad9854Read(AD9854_REG_DELTA1));
    00341     rprintfu08(ad9854Read(AD9854_REG_DELTA0));
    00342     rprintfCRLF();
    00343
    00344     rprintfStr("Update Clock:     0x");
    00345     rprintfu08(ad9854Read(AD9854_REG_UPDCLOCK3));
    00346     rprintfu08(ad9854Read(AD9854_REG_UPDCLOCK2));
    00347     rprintfu08(ad9854Read(AD9854_REG_UPDCLOCK1));
    00348     rprintfu08(ad9854Read(AD9854_REG_UPDCLOCK0));
    00349     rprintfCRLF();
    00350
    00351     rprintfStr("Ramp Rate   :       0x");
    00352     rprintfu08(ad9854Read(AD9854_REG_RAMPCLOCK2));
    00353     rprintfu08(ad9854Read(AD9854_REG_RAMPCLOCK1));
    00354     rprintfu08(ad9854Read(AD9854_REG_RAMPCLOCK0));
    00355     rprintfCRLF();
    00356
    00357     rprintfStr("Control     :     0x");
    00358     rprintfu08(ad9854Read(AD9854_REG_CTRL3));
    00359     rprintfu08(ad9854Read(AD9854_REG_CTRL2));
    00360     rprintfu08(ad9854Read(AD9854_REG_CTRL1));
    00361     rprintfu08(ad9854Read(AD9854_REG_CTRL0));
    00362     rprintfCRLF();
    00363
    00364     rprintfStr("Amplitude I :         0x");
    00365     rprintfu08(ad9854Read(AD9854_REG_AMPLIH));
    00366     rprintfu08(ad9854Read(AD9854_REG_AMPLIL));
    00367     rprintfCRLF();
    00368
    00369     rprintfStr("Amplitude Q :         0x");
    00370     rprintfu08(ad9854Read(AD9854_REG_AMPLQH));
    00371     rprintfu08(ad9854Read(AD9854_REG_AMPLQL));
    00372     rprintfCRLF();
    00373
    00374 }
    00375