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);
    }
}
Committer:
sophtware
Date:
Sun Apr 06 16:50:53 2014 +0000
Revision:
2:86284a0a46ca
Parent:
1:162fd9241279
Initial Publish

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sophtware 0:4e016941c366 1 #include "DS1077.h"
sophtware 0:4e016941c366 2 #include "mbed.h"
sophtware 0:4e016941c366 3
sophtware 0:4e016941c366 4 #include "stdarg.h" // For debugOut use of the ... parameter and va_list
sophtware 0:4e016941c366 5
sophtware 0:4e016941c366 6 DS1077::DS1077(I2C *i2c, Serial *pc) : _i2c(i2c), _debug(pc)
sophtware 0:4e016941c366 7 {
sophtware 0:4e016941c366 8 }
sophtware 0:4e016941c366 9
sophtware 0:4e016941c366 10 void DS1077::write()
sophtware 0:4e016941c366 11 {
sophtware 0:4e016941c366 12 char cmd[1];
sophtware 0:4e016941c366 13 cmd[0] = CMD_E2;
sophtware 0:4e016941c366 14 if (_i2c->write(DS1077_ADDRESS, cmd, 1) != 0)
sophtware 0:4e016941c366 15 debugOut("DS1077::write: Failed issuing write command to register 0x%X\r\n", CMD_E2);
sophtware 0:4e016941c366 16 }
sophtware 0:4e016941c366 17
sophtware 0:4e016941c366 18 void DS1077::setShutdownControl(DS1077::pdnType pdn)
sophtware 0:4e016941c366 19 {
sophtware 0:4e016941c366 20 short temp = i2cTwoByteRead(CMD_DIV); // Read the current register value
sophtware 0:4e016941c366 21
sophtware 0:4e016941c366 22 switch (pdn)
sophtware 0:4e016941c366 23 {
sophtware 0:4e016941c366 24 case NONE:
sophtware 0:4e016941c366 25 temp &= ~0x6000;
sophtware 0:4e016941c366 26 break;
sophtware 0:4e016941c366 27 case CTRL1:
sophtware 0:4e016941c366 28 temp &= ~0x4000;
sophtware 0:4e016941c366 29 temp |= 0x2000;
sophtware 0:4e016941c366 30 break;
sophtware 1:162fd9241279 31 case CTRL0:
sophtware 0:4e016941c366 32 temp &= ~0x2000;
sophtware 0:4e016941c366 33 temp |= 0x4000;
sophtware 0:4e016941c366 34 break;
sophtware 0:4e016941c366 35 case EITHER:
sophtware 0:4e016941c366 36 temp |= 0x6000;
sophtware 0:4e016941c366 37 break;
sophtware 0:4e016941c366 38 }
sophtware 0:4e016941c366 39
sophtware 0:4e016941c366 40 i2cTwoByteWrite(CMD_DIV, (char)(temp>>8), (char)temp); // Write register value back
sophtware 0:4e016941c366 41 }
sophtware 0:4e016941c366 42
sophtware 0:4e016941c366 43 char DS1077::address()
sophtware 0:4e016941c366 44 {
sophtware 0:4e016941c366 45 return (char)(i2cTwoByteRead(CMD_BUS) & 0x7);
sophtware 0:4e016941c366 46 }
sophtware 0:4e016941c366 47
sophtware 0:4e016941c366 48 void DS1077::setAddress(char addr)
sophtware 0:4e016941c366 49 {
sophtware 0:4e016941c366 50 short temp = i2cTwoByteRead(CMD_BUS) & 0xFFF8;
sophtware 0:4e016941c366 51 temp |= (addr & 0x7);
sophtware 0:4e016941c366 52 i2cTwoByteWrite(CMD_BUS, (char)(temp>>8), (char)temp);
sophtware 0:4e016941c366 53 }
sophtware 0:4e016941c366 54
sophtware 0:4e016941c366 55 DS1077::prescalerType DS1077::prescalerP0Divisor()
sophtware 0:4e016941c366 56 {
sophtware 0:4e016941c366 57 short temp = (i2cTwoByteRead(CMD_MUX) & 0x600) >> 9;
sophtware 0:4e016941c366 58
sophtware 0:4e016941c366 59 switch (temp)
sophtware 0:4e016941c366 60 {
sophtware 0:4e016941c366 61 case 0:
sophtware 0:4e016941c366 62 return X1;
sophtware 0:4e016941c366 63 case 1:
sophtware 0:4e016941c366 64 return X2;
sophtware 0:4e016941c366 65 case 2:
sophtware 0:4e016941c366 66 return X4;
sophtware 0:4e016941c366 67 case 3:
sophtware 0:4e016941c366 68 return X8;
sophtware 0:4e016941c366 69 }
sophtware 0:4e016941c366 70
sophtware 0:4e016941c366 71 return X1;
sophtware 0:4e016941c366 72 }
sophtware 0:4e016941c366 73
sophtware 0:4e016941c366 74 void DS1077::setPrescalerP0Divisor(DS1077::prescalerType prescaler)
sophtware 0:4e016941c366 75 {
sophtware 0:4e016941c366 76 short temp = i2cTwoByteRead(CMD_MUX); // Read the current register value
sophtware 0:4e016941c366 77
sophtware 0:4e016941c366 78 switch (prescaler)
sophtware 0:4e016941c366 79 {
sophtware 0:4e016941c366 80 case X1:
sophtware 0:4e016941c366 81 temp &= ~0x600;
sophtware 0:4e016941c366 82 break;
sophtware 0:4e016941c366 83 case X2:
sophtware 0:4e016941c366 84 temp = (~0x600 & temp | (0x1<<9));
sophtware 0:4e016941c366 85 break;
sophtware 0:4e016941c366 86 case X4:
sophtware 0:4e016941c366 87 temp = (~0x600 & temp | (0x2<<9));
sophtware 0:4e016941c366 88 break;
sophtware 0:4e016941c366 89 case X8:
sophtware 0:4e016941c366 90 temp |= 0x600;
sophtware 0:4e016941c366 91 break;
sophtware 0:4e016941c366 92 }
sophtware 0:4e016941c366 93
sophtware 0:4e016941c366 94 i2cTwoByteWrite(CMD_MUX, (char)(temp>>8), (char)temp); // Write register value back
sophtware 0:4e016941c366 95 }
sophtware 0:4e016941c366 96
sophtware 0:4e016941c366 97 DS1077::prescalerType DS1077::prescalerP1Divisor()
sophtware 0:4e016941c366 98 {
sophtware 0:4e016941c366 99 short temp = (i2cTwoByteRead(CMD_MUX) & 0x180) >> 7;
sophtware 0:4e016941c366 100
sophtware 0:4e016941c366 101 switch (temp)
sophtware 0:4e016941c366 102 {
sophtware 0:4e016941c366 103 case 0:
sophtware 0:4e016941c366 104 return X1;
sophtware 0:4e016941c366 105 case 1:
sophtware 0:4e016941c366 106 return X2;
sophtware 0:4e016941c366 107 case 2:
sophtware 0:4e016941c366 108 return X4;
sophtware 0:4e016941c366 109 case 3:
sophtware 0:4e016941c366 110 return X8;
sophtware 0:4e016941c366 111 }
sophtware 0:4e016941c366 112
sophtware 0:4e016941c366 113 return X1;
sophtware 0:4e016941c366 114 }
sophtware 0:4e016941c366 115
sophtware 0:4e016941c366 116 void DS1077::setPrescalerP1Divisor(DS1077::prescalerType prescaler)
sophtware 0:4e016941c366 117 {
sophtware 0:4e016941c366 118 short temp = i2cTwoByteRead(CMD_MUX); // Read the current register value
sophtware 0:4e016941c366 119
sophtware 0:4e016941c366 120 switch (prescaler)
sophtware 0:4e016941c366 121 {
sophtware 0:4e016941c366 122 case X1:
sophtware 0:4e016941c366 123 temp &= ~0x180;
sophtware 0:4e016941c366 124 break;
sophtware 0:4e016941c366 125 case X2:
sophtware 0:4e016941c366 126 temp = (~0x180 & temp | (0x1<<7));
sophtware 0:4e016941c366 127 break;
sophtware 0:4e016941c366 128 case X4:
sophtware 0:4e016941c366 129 temp = (~0x180 & temp | (0x2<<7));
sophtware 0:4e016941c366 130 break;
sophtware 0:4e016941c366 131 case X8:
sophtware 0:4e016941c366 132 temp |= 0x180;
sophtware 0:4e016941c366 133 break;
sophtware 0:4e016941c366 134 }
sophtware 0:4e016941c366 135
sophtware 0:4e016941c366 136 i2cTwoByteWrite(CMD_MUX, (char)(temp>>8), (char)temp); // Write register value back
sophtware 0:4e016941c366 137 }
sophtware 0:4e016941c366 138
sophtware 0:4e016941c366 139 void DS1077::clearRegisterBit(const char regAddr, const char bitMask)
sophtware 0:4e016941c366 140 {
sophtware 0:4e016941c366 141 char temp = i2cRead(regAddr); // Read the current register value
sophtware 0:4e016941c366 142 temp &= ~bitMask; // Clear the bit from the value
sophtware 0:4e016941c366 143 i2cWrite(regAddr, temp); // Write register value back
sophtware 0:4e016941c366 144 }
sophtware 0:4e016941c366 145
sophtware 0:4e016941c366 146 void DS1077::setRegisterBit(const char regAddr, const char bitMask)
sophtware 0:4e016941c366 147 {
sophtware 0:4e016941c366 148 char temp = i2cRead(regAddr); // Read the current register value
sophtware 0:4e016941c366 149 temp |= bitMask; // Set the bit in the value
sophtware 0:4e016941c366 150 i2cWrite(regAddr, temp); // Write register value back
sophtware 0:4e016941c366 151 }
sophtware 0:4e016941c366 152
sophtware 0:4e016941c366 153 void DS1077::clearTwoByteRegisterBit(const char regAddr, const short bitMask)
sophtware 0:4e016941c366 154 {
sophtware 0:4e016941c366 155 short temp = i2cTwoByteRead(regAddr); // Read the current register value
sophtware 0:4e016941c366 156 temp &= ~bitMask; // Clear the bit from the value
sophtware 0:4e016941c366 157 wait_ms(1);
sophtware 0:4e016941c366 158 i2cTwoByteWrite(regAddr, (char)(temp>>8), (char)temp); // Write register value back
sophtware 0:4e016941c366 159 }
sophtware 0:4e016941c366 160
sophtware 0:4e016941c366 161 void DS1077::setTwoByteRegisterBit(const char regAddr, const short bitMask)
sophtware 0:4e016941c366 162 {
sophtware 0:4e016941c366 163 short temp = i2cTwoByteRead(regAddr); // Read the current register value
sophtware 0:4e016941c366 164 temp |= bitMask; // Set the bit in the value
sophtware 0:4e016941c366 165 wait_ms(1);
sophtware 0:4e016941c366 166 i2cTwoByteWrite(regAddr, (char)(temp>>8), (char)temp); // Write register value back
sophtware 0:4e016941c366 167 }
sophtware 0:4e016941c366 168
sophtware 0:4e016941c366 169 char DS1077::i2cRead(char regAddr)
sophtware 0:4e016941c366 170 {
sophtware 0:4e016941c366 171 _i2c->start(); // Start
sophtware 0:4e016941c366 172 if (_i2c->write(DS1077_ADDRESS)!=1) // A write to device
sophtware 0:4e016941c366 173 debugOut("DS1077::i2cRead: Oscillator failed to respond to write request at address 0x%X\r\n", DS1077_ADDRESS);
sophtware 0:4e016941c366 174
sophtware 0:4e016941c366 175 if (_i2c->write(regAddr)!=1) // Register to read
sophtware 0:4e016941c366 176 debugOut("DS1077::i2cRead: Oscillator at address 0x%X did not acknowledge register 0x%X\r\n", DS1077_ADDRESS, regAddr);
sophtware 0:4e016941c366 177
sophtware 0:4e016941c366 178 _i2c->start();
sophtware 0:4e016941c366 179 if (_i2c->write(DS1077_ADDRESS|0x01)!=1) // Read from device
sophtware 0:4e016941c366 180 debugOut("DS1077::i2cRead: Oscillator failed to respond to read request at address 0x%X\r\n", DS1077_ADDRESS);
sophtware 0:4e016941c366 181
sophtware 0:4e016941c366 182 char result = _i2c->read(READ_NAK); // Read the data
sophtware 0:4e016941c366 183 _i2c->stop();
sophtware 0:4e016941c366 184
sophtware 0:4e016941c366 185 return result;
sophtware 0:4e016941c366 186 }
sophtware 0:4e016941c366 187
sophtware 0:4e016941c366 188 void DS1077::i2cWrite(char regAddr, char msb)
sophtware 0:4e016941c366 189 {
sophtware 0:4e016941c366 190 char cmd[2];
sophtware 0:4e016941c366 191 cmd[0] = regAddr;
sophtware 0:4e016941c366 192 cmd[1] = msb;
sophtware 0:4e016941c366 193 if (_i2c->write(DS1077_ADDRESS, cmd, 2) != 0)
sophtware 0:4e016941c366 194 debugOut("DS1077::i2cWrite: Failed writing msb (%d, 0x%X) to register 0x%X\r\n", msb, regAddr);
sophtware 0:4e016941c366 195 }
sophtware 0:4e016941c366 196
sophtware 0:4e016941c366 197 short DS1077::i2cTwoByteRead(char regAddr)
sophtware 0:4e016941c366 198 {
sophtware 0:4e016941c366 199 _i2c->start(); // Start
sophtware 0:4e016941c366 200 if (_i2c->write(DS1077_ADDRESS)!=1) // A write to device
sophtware 0:4e016941c366 201 debugOut("DS1077::i2cRead: Oscillator failed to respond to write request at address 0x%X\r\n", DS1077_ADDRESS);
sophtware 0:4e016941c366 202
sophtware 0:4e016941c366 203 if (_i2c->write(regAddr)!=1) // Register to read
sophtware 0:4e016941c366 204 debugOut("DS1077::i2cRead: Oscillator at address 0x%X did not acknowledge register 0x%X\r\n", DS1077_ADDRESS, regAddr);
sophtware 0:4e016941c366 205
sophtware 0:4e016941c366 206 _i2c->start();
sophtware 0:4e016941c366 207 if (_i2c->write(DS1077_ADDRESS|0x01)!=1) // Read from device
sophtware 0:4e016941c366 208 debugOut("DS1077::i2cRead: Oscillator failed to respond to read request at address 0x%X\r\n", DS1077_ADDRESS);
sophtware 0:4e016941c366 209
sophtware 0:4e016941c366 210 char msb = _i2c->read(READ_ACK); // Read the data
sophtware 0:4e016941c366 211 char lsb = _i2c->read(READ_NAK); // Read the data
sophtware 0:4e016941c366 212 _i2c->stop();
sophtware 0:4e016941c366 213
sophtware 0:4e016941c366 214 return ((short)msb<<8)|lsb;
sophtware 0:4e016941c366 215 }
sophtware 0:4e016941c366 216
sophtware 0:4e016941c366 217 void DS1077::i2cTwoByteWrite(char regAddr, char msb, char lsb)
sophtware 0:4e016941c366 218 {
sophtware 0:4e016941c366 219 char cmd[3];
sophtware 0:4e016941c366 220 cmd[0] = regAddr;
sophtware 0:4e016941c366 221 cmd[1] = msb;
sophtware 0:4e016941c366 222 cmd[2] = lsb;
sophtware 0:4e016941c366 223 if (_i2c->write(DS1077_ADDRESS, cmd, 3) != 0)
sophtware 0:4e016941c366 224 debugOut("DS1077::i2cWrite: Failed writing msb (%d, 0x%X) and lsb (%d, 0x%X) to register 0x%X\r\n", msb, lsb, regAddr);
sophtware 0:4e016941c366 225 }
sophtware 0:4e016941c366 226
sophtware 0:4e016941c366 227 void DS1077::debugOut(const char * format, ...)
sophtware 0:4e016941c366 228 {
sophtware 0:4e016941c366 229 if (_debug == NULL)
sophtware 0:4e016941c366 230 return;
sophtware 0:4e016941c366 231
sophtware 0:4e016941c366 232 va_list arg;
sophtware 0:4e016941c366 233 _debug->printf(format, arg);
sophtware 0:4e016941c366 234 }