General usable MCP4728 quad DAC implementation only limited function has to be used together with the DevInterface lib
Dependents: mbedSerialInterface_talkback2 MCP4728test mbedSerialInterface_sequencer
mcp4728.cpp@0:7a0ebc527fb9, 2015-10-23 (annotated)
- 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?
User | Revision | Line number | New 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 | } |