Library for interfacing with AD9837, generate Sine/Triangular/Square wave

Files at this revision

API Documentation at this revision

Comitter:
nicolas97
Date:
Tue Jun 30 08:25:56 2015 +0000
Commit message:
Library to interface with AD9837 (function generator)

Changed in this revision

AD9837.cpp Show annotated file Show diff for this revision Revisions of this file
AD9837.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AD9837.cpp	Tue Jun 30 08:25:56 2015 +0000
@@ -0,0 +1,67 @@
+#include "AD9837.h"
+#include "mbed.h"
+
+#define REG_FREQ1   0x8000
+#define REG_FREQ0   0x4000
+#define REG_PHASE0  0xC000
+#define REG_PHASE1  0xE000
+
+#define REG_B28     0x2000
+#define REG_HLB     0x1000
+#define REG_FSEL    0x0800
+#define REG_PSEL    0x0400
+#define REG_PINSW   0x0200
+#define REG_RESET   0x0100
+#define REG_SLEEP1  0x0080
+#define REG_SLEEP12 0x0040
+#define REG_OPBITEN 0x0020
+#define REG_SIGNPIB 0x0010
+#define REG_DIV2    0x0008
+#define REG_MODE    0x0002
+
+#define SIGN_OUTPUT_MASK (REG_OPBITEN | REG_SIGNPIB | REG_DIV2 | REG_MODE)
+
+AD9837::AD9837(PinName mosi, PinName miso, PinName sclk, PinName cs) : _spi(mosi, miso, sclk), _cs(cs) {
+    
+    _spi.format(8, 2);
+    _spi.frequency(1000000);
+}
+
+void AD9837::writeReg(uint16_t value)
+{
+    _cs=0;
+    wait_us(10);
+    _spi.write(value >> 8);
+    _spi.write(value & 0xFF);
+    wait_us(10);
+    _cs=1;
+}
+
+void AD9837::setFrequencyWord(unsigned int reg, uint32_t frequency)
+{
+    writeReg((reg?REG_FREQ1:REG_FREQ0) | (frequency & 0x3FFF));
+    writeReg((reg?REG_FREQ1:REG_FREQ0) | ((frequency >> 14) & 0x3FFF));
+}
+
+void AD9837::setPhaseWord(unsigned int reg, uint32_t phase)
+{
+    writeReg((reg?REG_PHASE1:REG_PHASE0) | (phase & 0x0FFF));
+}
+
+void AD9837::setSignOutput(SignOutput out)
+{
+    m_reg = (m_reg & ~SIGN_OUTPUT_MASK) | out;
+    writeReg(m_reg);
+}
+
+void AD9837::setOutputMode(OutputMode out)
+{
+    if(out == OUTPUT_MODE_TRIANGLE) {
+        m_reg = (m_reg & ~SIGN_OUTPUT_MASK) | out;
+    } if(out == OUTPUT_MODE_SINE) {
+        m_reg &= ~REG_MODE;
+    }else {
+        m_reg = 0x2A;
+    }
+    writeReg(m_reg);
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AD9837.h	Tue Jun 30 08:25:56 2015 +0000
@@ -0,0 +1,52 @@
+#include "mbed.h"
+
+enum SignOutput {
+    SIGN_OUTPUT_NONE        = 0x0000,
+    SIGN_OUTPUT_MSB         = 0x0028,
+    SIGN_OUTPUT_MSB_2       = 0x0020,
+    SIGN_OUTPUT_COMPARATOR  = 0x0038,
+};
+
+enum OutputMode {
+    OUTPUT_MODE_SINE        = 0x0000,
+    OUTPUT_MODE_TRIANGLE    = 0x0002,
+    OUTPUT_MODE_SQUARE      = 0x0004,
+};
+
+class AD9837
+{
+public:
+    AD9837(PinName mosi, PinName miso, PinName sclk, PinName cs);
+    void setFrequencyWord(unsigned int reg, uint32_t frequency);
+    void setPhaseWord(unsigned int reg, uint32_t phase);
+    void setSignOutput(SignOutput out);
+    void setOutputMode(OutputMode out);
+
+    inline uint32_t computeFrequencyWord(uint32_t frequency) {
+        // This is a manual expansion of (frequency * 2^28) / m_frequency_mhz
+        // Since it doesn't require 64 bit multiplies or divides, it results in
+        // substantially smaller code sizes.
+        uint32_t lval = ((frequency & 0xFF) << 22) / (15625l * m_frequency_mhz);
+        uint32_t mval = ((frequency & 0xFF00) << 14) / (15625l * m_frequency_mhz);
+        uint32_t hval = ((frequency & 0xFF0000) << 6) / (15625l * m_frequency_mhz);
+        return (hval << 16) + (mval << 8) + lval;
+    }
+
+    inline void setFrequency(unsigned char reg, long int frequency) {
+        frequency = this->computeFrequencyWord(frequency);
+        this->setFrequencyWord(reg, frequency);
+    }
+
+    inline void setFrequency(unsigned char reg, float frequency) {
+        this->setFrequencyWord(reg, (frequency * (1l << 28)) / (m_frequency_mhz * 1000000));
+    }
+
+protected:
+    void writeReg(uint16_t value);
+    int m_frequency_mhz;
+    uint16_t m_reg;
+
+private:
+    SPI _spi;
+    DigitalOut _cs;
+};
\ No newline at end of file