General usable MCP4728 quad DAC implementation only limited function has to be used together with the DevInterface lib

Dependents:   mbedSerialInterface_talkback2 MCP4728test mbedSerialInterface_sequencer

Committer:
wbeaumont
Date:
Fri Oct 23 19:35:27 2015 +0000
Revision:
0:7a0ebc527fb9
Child:
1:cd7c70a46739
set ch1 hard coding is working a lot of copied code not  checked

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wbeaumont 0:7a0ebc527fb9 1 #include "mcp4728.h"
wbeaumont 0:7a0ebc527fb9 2 #include "mbed.h"
wbeaumont 0:7a0ebc527fb9 3
wbeaumont 0:7a0ebc527fb9 4
wbeaumont 0:7a0ebc527fb9 5 #define VERSION_MCP4728_SRC "0.02"
wbeaumont 0:7a0ebc527fb9 6 // verions 0.02 has a fixed setDAC but now ch1 reacts on the heart beat some bit maniputation error in the setDac
wbeaumont 0:7a0ebc527fb9 7
wbeaumont 0:7a0ebc527fb9 8 #define CMDFAST 0
wbeaumont 0:7a0ebc527fb9 9 #define CMDWRITEDAC 2 // writes to the DAC and / or eeprom depending on the write funcion
wbeaumont 0:7a0ebc527fb9 10 //#define CMDWRITEI2CADDR 3 // handled in a different class
wbeaumont 0:7a0ebc527fb9 11 #define CMDWRITEVREF 4
wbeaumont 0:7a0ebc527fb9 12 #define CMDWRITEGAIN 6
wbeaumont 0:7a0ebc527fb9 13 #define CMDWRITEPWDDOWN 5
wbeaumont 0:7a0ebc527fb9 14
wbeaumont 0:7a0ebc527fb9 15 #define WRITEFCTMULTI 0 // write to multiple DAC ch given by ch selectio bits
wbeaumont 0:7a0ebc527fb9 16 #define WRITEFCTSEQ 2 // write to DAC AND eeprom, from ch given in ch selection bits to D
wbeaumont 0:7a0ebc527fb9 17 #define WRITEFCTSINGLE 3 // write to a singe DAC AND eeprom ch given in ch selection bits
wbeaumont 0:7a0ebc527fb9 18
wbeaumont 0:7a0ebc527fb9 19 MCP4728::MCP4728(I2CInterface* i2cinterface, int device_address_bits ): _i2c_interface(i2cinterface) ,
wbeaumont 0:7a0ebc527fb9 20 getVersion( VERSION_MCP4728_HDR,VERSION_MCP4728_SRC, __TIME__, __DATE__)
wbeaumont 0:7a0ebc527fb9 21 {
wbeaumont 0:7a0ebc527fb9 22
wbeaumont 0:7a0ebc527fb9 23 // Assemble the full I2C device address.
wbeaumont 0:7a0ebc527fb9 24 _device_address = 0xC0; // Prime the full device address with the device code.
wbeaumont 0:7a0ebc527fb9 25 _device_address |= (device_address_bits<<1);
wbeaumont 0:7a0ebc527fb9 26 // next has to be read back from the device but
wbeaumont 0:7a0ebc527fb9 27
wbeaumont 0:7a0ebc527fb9 28 for ( int ch=0;ch<4;ch++) {
wbeaumont 0:7a0ebc527fb9 29 ChCfg[ch].pwr=Normal;
wbeaumont 0:7a0ebc527fb9 30 ChCfg[ch].vref=InternRef;
wbeaumont 0:7a0ebc527fb9 31 ChCfg[ch].gain=GainX2;
wbeaumont 0:7a0ebc527fb9 32 }
wbeaumont 0:7a0ebc527fb9 33 }
wbeaumont 0:7a0ebc527fb9 34
wbeaumont 0:7a0ebc527fb9 35 int MCP4728::getDACvalue(int& value, int ch){
wbeaumont 0:7a0ebc527fb9 36 // has to limit to reading only the dac value not the other items.
wbeaumont 0:7a0ebc527fb9 37 enum PowerMode mode; enum PowerMode mode_eeprom; int dac_value; int dac_value_eeprom; bool eeprom_write_in_progress;
wbeaumont 0:7a0ebc527fb9 38 int status = read( mode, mode_eeprom, dac_value, dac_value_eeprom, eeprom_write_in_progress);
wbeaumont 0:7a0ebc527fb9 39 value=dac_value;
wbeaumont 0:7a0ebc527fb9 40 return status;
wbeaumont 0:7a0ebc527fb9 41 }
wbeaumont 0:7a0ebc527fb9 42
wbeaumont 0:7a0ebc527fb9 43 int MCP4728::read(enum PowerMode& mode, enum PowerMode& mode_eeprom, int& dac_value, int& dac_value_eeprom, bool& eeprom_write_in_progress)
wbeaumont 0:7a0ebc527fb9 44 {
wbeaumont 0:7a0ebc527fb9 45 char data[5];
wbeaumont 0:7a0ebc527fb9 46 int result;
wbeaumont 0:7a0ebc527fb9 47
wbeaumont 0:7a0ebc527fb9 48 // Read the raw data from the device.
wbeaumont 0:7a0ebc527fb9 49 result = _i2c_interface->read(_device_address, data, sizeof(data)/sizeof(*data), false);
wbeaumont 0:7a0ebc527fb9 50
wbeaumont 0:7a0ebc527fb9 51 // Parse the raw data, extracting our fields. Refer to MCP4728 ref manual, section 6.2
wbeaumont 0:7a0ebc527fb9 52 if (result == 0)
wbeaumont 0:7a0ebc527fb9 53 {
wbeaumont 0:7a0ebc527fb9 54 eeprom_write_in_progress = (data[0] & 0x80)? false:true;
wbeaumont 0:7a0ebc527fb9 55
wbeaumont 0:7a0ebc527fb9 56 mode = (enum PowerMode) ((data[0] & 0x06)>>1);
wbeaumont 0:7a0ebc527fb9 57
wbeaumont 0:7a0ebc527fb9 58 dac_value = (data[1]<<4) + (data[2]>>4);
wbeaumont 0:7a0ebc527fb9 59
wbeaumont 0:7a0ebc527fb9 60 mode_eeprom = (enum PowerMode)((data[3] & 0x60)>>5);
wbeaumont 0:7a0ebc527fb9 61
wbeaumont 0:7a0ebc527fb9 62 dac_value_eeprom = ((data[3] & 0x0F) <<8) + data[4];
wbeaumont 0:7a0ebc527fb9 63 }
wbeaumont 0:7a0ebc527fb9 64
wbeaumont 0:7a0ebc527fb9 65 return result;
wbeaumont 0:7a0ebc527fb9 66 }
wbeaumont 0:7a0ebc527fb9 67
wbeaumont 0:7a0ebc527fb9 68
wbeaumont 0:7a0ebc527fb9 69 int MCP4728::setDACvalue( int value, int ch){
wbeaumont 0:7a0ebc527fb9 70 char data[3], tmp ;
wbeaumont 0:7a0ebc527fb9 71 /* data[0] = CMDWRITEDAC << 6; // select write DAC function
wbeaumont 0:7a0ebc527fb9 72 data[0] = data[0] | WRITEFCTMULTI << 4 ; // select write multi ch no eeprom
wbeaumont 0:7a0ebc527fb9 73 ch =ch & 3;
wbeaumont 0:7a0ebc527fb9 74 tmp =(char) ch; // select the channel
wbeaumont 0:7a0ebc527fb9 75 data[0] = data[0] | tmp ;
wbeaumont 0:7a0ebc527fb9 76 data[0] = data[0] | 0 ; // update now , assuming !LDAC =0
wbeaumont 0:7a0ebc527fb9 77 */
wbeaumont 0:7a0ebc527fb9 78 data[2] = 0xFF & (char)value;
wbeaumont 0:7a0ebc527fb9 79 /* value=value >>8;
wbeaumont 0:7a0ebc527fb9 80 data[1] = 0x0F & (char)value;
wbeaumont 0:7a0ebc527fb9 81 data[1] = data[1] | (char)( ChCfg[ch].gain <<4); //set gain
wbeaumont 0:7a0ebc527fb9 82 data[1] = data[1] | (char)( ChCfg[ch].pwr <<5); // set pwr mode
wbeaumont 0:7a0ebc527fb9 83 data[1] = data[1] | (char)( ChCfg[ch].vref <<7); // set pwr mode
wbeaumont 0:7a0ebc527fb9 84 */
wbeaumont 0:7a0ebc527fb9 85 data[0]= 0x52; // 0b0101 0010 ch 1 !UDAC=0
wbeaumont 0:7a0ebc527fb9 86 data[1]= 0x17; // 0b0000 0111 ref=Vdd, pwd =0 normal ; gain =1 d11=0 ,111,
wbeaumont 0:7a0ebc527fb9 87 return _i2c_interface->write(_device_address, data, sizeof(data)/sizeof(*data), false);
wbeaumont 0:7a0ebc527fb9 88
wbeaumont 0:7a0ebc527fb9 89
wbeaumont 0:7a0ebc527fb9 90 }
wbeaumont 0:7a0ebc527fb9 91
wbeaumont 0:7a0ebc527fb9 92
wbeaumont 0:7a0ebc527fb9 93
wbeaumont 0:7a0ebc527fb9 94
wbeaumont 0:7a0ebc527fb9 95 int MCP4728::write(enum PowerMode mode, int dac_value, bool writeToEeprom)
wbeaumont 0:7a0ebc527fb9 96 {
wbeaumont 0:7a0ebc527fb9 97 char data[3]={0};
wbeaumont 0:7a0ebc527fb9 98 int write_command;
wbeaumont 0:7a0ebc527fb9 99
wbeaumont 0:7a0ebc527fb9 100 //Which write command are we to use?
wbeaumont 0:7a0ebc527fb9 101 if (writeToEeprom == true)
wbeaumont 0:7a0ebc527fb9 102 {
wbeaumont 0:7a0ebc527fb9 103 //Write DAC Register and EEPROM
wbeaumont 0:7a0ebc527fb9 104 write_command = 3;
wbeaumont 0:7a0ebc527fb9 105 }
wbeaumont 0:7a0ebc527fb9 106 else
wbeaumont 0:7a0ebc527fb9 107 {
wbeaumont 0:7a0ebc527fb9 108 //Write DAC Register
wbeaumont 0:7a0ebc527fb9 109 write_command = 2;
wbeaumont 0:7a0ebc527fb9 110 }
wbeaumont 0:7a0ebc527fb9 111
wbeaumont 0:7a0ebc527fb9 112 //Assemble our three bytes of data - Refer to MCP4728 ref manual, section 6.
wbeaumont 0:7a0ebc527fb9 113 data[0] = (write_command <<5) | ((int)mode<<1);
wbeaumont 0:7a0ebc527fb9 114 data[1] = (dac_value>>4);
wbeaumont 0:7a0ebc527fb9 115 data[2] = (dac_value<<4);
wbeaumont 0:7a0ebc527fb9 116
wbeaumont 0:7a0ebc527fb9 117 // Now write them to the device.
wbeaumont 0:7a0ebc527fb9 118 return _i2c_interface->write(_device_address, data, sizeof(data)/sizeof(*data), false);
wbeaumont 0:7a0ebc527fb9 119 }