Maxim DS1077 EconOscillator/Divider Library

Maxim DS1077 EconOscillator/Divider

This class wraps the functions of the DS1077 oscillator into a usable class for mBed. The oscillator uses I2C to communicate with the host MCU. This oscillator output a square wave, so if you're looking for a sine wave - this isn't it.

Be sure to download the DATASHEET (You'll need it to work with this chip). You can also purchase a breakout board from SparkFun. Be sure to ground the CTRL1 and CTRL0 pins if you don't plan on using them.

This library was created using the mbed NXP LPC11U24. Pins p27 and p28 were used for the I2C functions. Be sure to install 1K pull-up resistors on both lines.

Here's the output from the OUT1 pin on my scope after running the sample code below:

/media/uploads/sophtware/ds1077-32khz.png

Below is some sample code that sets the oscillator OUT2 pin to 16.67MHz and the OUT1 pin to 32kHz. It then outputs the content of all the control registers. You'll need the serial debug setup for your mBed. If you still need the serial driver for your mbed, you can get it here.

Sample Code

#include "mbed.h"
#include "DS1077.h"

I2C i2c(p28, p27);       // sda, scl

// Comment out all of the references to 'pc' on this page if you don't have the 
// serial debug driver for your mbed board installed on your computer. If you do,
// I personally like to use Putty as the terminal window to capture debug messages.
Serial pc(USBTX, USBRX); // tx, rx

// Again, remove the '&pc' parameter if you're not debugging.
DS1077 osc(&i2c, &pc);

DigitalOut myled(LED1);

int main() 
{
    pc.printf("** DS1077 EconOscillator **\r\n");

    osc.setSelect();
    wait_ms(1);
    // Set OUT2 to ~16.67MHz
    osc.setPrescalerP0Divisor(DS1077::X8);
    wait_ms(1);
    // Set OUT1 to ~32kHz
    osc.setPrescalerP1Divisor(DS1077::X4);
    wait_ms(1);
    osc.setDivisor(0xFFF);
    wait_ms(1);

    pc.printf("DIV: 0x%X\r\n", osc.divRegister()&0x0000FFFF);
    wait_ms(1);
    pc.printf("MUX: 0x%X\r\n", osc.muxRegister()&0x0000FFFF);
    wait_ms(1);
    pc.printf("BUS: 0x%X\r\n", osc.busRegister());

//    osc.write();

    while(1) {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }
}

DS1077.h

Committer:
sophtware
Date:
2014-04-06
Revision:
2:86284a0a46ca
Parent:
0:4e016941c366

File content as of revision 2:86284a0a46ca:

/*
    Maxim DS1077 EconOscillator/Divider Library
    By: Michael Lange
    Date: April 5, 2014
    License: This code is public domain.
 
    This class wraps the functions of the DS1077 oscillator divider 
    into a usable class that exposes all functions to your project.
 
 */
 
 
#ifndef DS1077_H
#define DS1077_H

#include "mbed.h"

#define DS1077_ADDRESS   0xB0    // Default (A0=0, A1=0, A3=0) unprogrammed address.

#define READ_ACK 1               // For mbed I2C Read method.
#define READ_NAK 0 

#define CMD_DIV 0x01            // Command registers
#define CMD_MUX 0x02
#define CMD_BUS 0x0D
#define CMD_E2  0x3F

//! Maxim DS1077 EconOscillator/Divider Library
//! This class wraps the function in the DS1077 oscillator.
class DS1077
{
public:
    //! Constructs an DS1077 object and associates an I2C and optional 
    //! Serial debug object.
    //! @param *i2c The I2C object to use for the sensor.
    //! @param *pc An optional serial debug connection object.
    DS1077(I2C *i2c, Serial *pc = NULL);

    //! Shutdown control configuration for PINs CTRL1 and CTRL0. If not
    //! using these pins they should be grounded.
    enum pdnType { NONE, CTRL1, CTRL0, EITHER };
    //! Prescaler divisor by 1, 2, 4, or 8. This does an initial divide 
    //! by the chip's master clock, which is selected by the part number.
    //! For the SparkFun board this is 133.333MHz
    enum prescalerType { X1, X2, X4, X8 };

    //! Sets the function for the shutdown pins PDN1 and PDN0 in the MUX word.
    void setShutdownControl(DS1077::pdnType pdn);
    
    //! Sets the EN0 bit in the MUX word.
    void setEnable() { setTwoByteRegisterBit(CMD_MUX, 0x800); }
    //! Clears the EN0 bit in the MUX word.
    void clearEnable() { clearTwoByteRegisterBit(CMD_MUX, 0x800); }
    //! Sets the SEL0 bit in the MUX word.
    void setSelect() { setTwoByteRegisterBit(CMD_MUX, 0x1000); }
    //! Clears the SEL0 bit in the MUX word.
    void clearSelect() { clearTwoByteRegisterBit(CMD_MUX, 0x1000); }
    //! Sets the DIV1 bit in the MUX word.
    void setDivisor() { setTwoByteRegisterBit(CMD_MUX, 0x40); }
    //! Clears the DIV1 bit in the MUX word.
    void clearDivisor() { clearTwoByteRegisterBit(CMD_MUX, 0x40); }
    //! Sets the WC bit in the BUS byte.
    void setWriteContent() { setTwoByteRegisterBit(CMD_BUS, 0x8); }
    //! Clears the WC bit in the BUS byte.
    void clearWriteContent() { clearTwoByteRegisterBit(CMD_BUS, 0x8); }
    
    //! Gets the address bits A2, A1, and A0 from the BUS byte.
    char address();
    //! Sets the address bits A2, A1, and A0 in the BUS byte.
    void setAddress(char addr);
    
    //! Gets the prescaler divisor set for P0 from 0M1 and 0M0 from the MUX word.
    DS1077::prescalerType prescalerP0Divisor();
    //! Sets the prescaler divisor for P0 into 0M1 and 0M0 in the MUX word.
    void setPrescalerP0Divisor(DS1077::prescalerType prescaler);
    //! Gets the prescaler divisor set for P1 from 1M1 and 1M0 from the MUX word.
    DS1077::prescalerType prescalerP1Divisor();
    //! Sets the prescaler divisor for P1 into 1M1 and 1M0 in the MUX word.
    void setPrescalerP1Divisor(DS1077::prescalerType prescaler);
    
    //! Gets the divisor set for OUT2 in the DIV word, which further divides the prescaled output.
    short divisor() { return (i2cTwoByteRead(CMD_DIV) >> 6); }
    //! Sets the divisor for OUT2 in the DIV word, which further divides the prescaled output.
    void setDivisor(short divisor) { divisor <<= 6; i2cTwoByteWrite(CMD_DIV, (char)(divisor>>8), (char)divisor); }

    //! Writes the contents of the registers to EEPROM when the WC bit is set.
    void write();

    //! Returns the contents of the DIV register as a short.
    short divRegister() { return i2cTwoByteRead(CMD_DIV); }
    //! Returns the contents of the MUX register as a short.
    short muxRegister() { return i2cTwoByteRead(CMD_MUX); }
    //! Returns the contents of the BUS register as a char.
    char busRegister() { return i2cRead(CMD_BUS); }

private:
    //! The I2C object we use to communicate with. It is not part of the 
    //! class so that it can be shared with other peripherals on the bus.
    I2C *_i2c;          
                        
    //! Set this in the constructor if you want the class to output debug messages.                        
    //! If you need to pair down your code, you can remove this and all the
    //! references to it in the code.
    Serial *_debug;     
 
    //! Debug method that mimics the printf function, but will output nothing if _debug has not
    //! been set. This means you can safely us it in your code and nothing will happen if you don't
    //! assign the _debug object.
    void debugOut(const char * format, ...);
    
    void clearRegisterBit(const char regAddr, const char bitMask);
    void setRegisterBit(const char regAddr, const char bitMask);
    void clearTwoByteRegisterBit(const char regAddr, const short bitMask);
    void setTwoByteRegisterBit(const char regAddr, const short bitMask);

    //! Helper functions to read one value from the I2C bus using the oscillator's address.
    char i2cRead(char regAddr);
    //! Helper functions to write one value from the I2C bus using the oscillator's address.
    void i2cWrite(char regAddr, char msb);
    //! Helper functions to read one value from the I2C bus using the oscillator's address.
    short i2cTwoByteRead(char regAddr);
    //! Helper functions to write one value from the I2C bus using the oscillator's address.
    void i2cTwoByteWrite(char regAddr, char msb, char lsb);
};

#endif // DS1077_H