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

AD9837.h

Committer:
nicolas97
Date:
2015-06-30
Revision:
0:fdfd54fe27dc

File content as of revision 0:fdfd54fe27dc:

#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;
};