lab5

Dependencies:   mbed

Committer:
wonner163
Date:
Thu Nov 23 14:51:58 2017 +0000
Revision:
0:6e724cc2761b
lab5

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wonner163 0:6e724cc2761b 1 /*
wonner163 0:6e724cc2761b 2 * MCP4922 - DAC library.
wonner163 0:6e724cc2761b 3 */
wonner163 0:6e724cc2761b 4
wonner163 0:6e724cc2761b 5 #include "mbed.h"
wonner163 0:6e724cc2761b 6 #include "MCP4922.h"
wonner163 0:6e724cc2761b 7
wonner163 0:6e724cc2761b 8 using namespace mbed;
wonner163 0:6e724cc2761b 9
wonner163 0:6e724cc2761b 10 int dac =0;
wonner163 0:6e724cc2761b 11
wonner163 0:6e724cc2761b 12 MCP4922::MCP4922(PinName mosi, PinName sclk, PinName cs) : _spi(mosi, NC, sclk) {
wonner163 0:6e724cc2761b 13
wonner163 0:6e724cc2761b 14 int i;
wonner163 0:6e724cc2761b 15 _ndacs = 1;
wonner163 0:6e724cc2761b 16 _ncs_array = new DigitalOut*[ _ndacs ];
wonner163 0:6e724cc2761b 17 for (i=0; i<_ndacs; i++) {
wonner163 0:6e724cc2761b 18 _ncs_array[i] = new DigitalOut(cs);
wonner163 0:6e724cc2761b 19 }
wonner163 0:6e724cc2761b 20
wonner163 0:6e724cc2761b 21 // Initialise the DAC SPI interface.
wonner163 0:6e724cc2761b 22 _init();
wonner163 0:6e724cc2761b 23 }
wonner163 0:6e724cc2761b 24
wonner163 0:6e724cc2761b 25 // Destructor
wonner163 0:6e724cc2761b 26 MCP4922::~MCP4922() {
wonner163 0:6e724cc2761b 27
wonner163 0:6e724cc2761b 28 // Before destroying the object, shut down all the chips.
wonner163 0:6e724cc2761b 29 //shdn_all();
wonner163 0:6e724cc2761b 30
wonner163 0:6e724cc2761b 31 // Delete all the NCS DigitalOut objects and the array pointing to
wonner163 0:6e724cc2761b 32 // them.
wonner163 0:6e724cc2761b 33 int i;
wonner163 0:6e724cc2761b 34 for (i=0; i<_ndacs; i++) {
wonner163 0:6e724cc2761b 35 delete _ncs_array[i];
wonner163 0:6e724cc2761b 36 }
wonner163 0:6e724cc2761b 37 delete [] _ncs_array;
wonner163 0:6e724cc2761b 38
wonner163 0:6e724cc2761b 39 // Delete the LDAC DigitalOut object if it exists.
wonner163 0:6e724cc2761b 40 if (_latched ) delete _nldac;
wonner163 0:6e724cc2761b 41 }
wonner163 0:6e724cc2761b 42
wonner163 0:6e724cc2761b 43 // Initialise SPI interface.
wonner163 0:6e724cc2761b 44 void MCP4922::_init() {
wonner163 0:6e724cc2761b 45
wonner163 0:6e724cc2761b 46 // Set up the SPI for 16-bit values (12-bit + 4 command bits) and mode 0.
wonner163 0:6e724cc2761b 47 _spi.format(16, 0);
wonner163 0:6e724cc2761b 48
wonner163 0:6e724cc2761b 49 // Start with all the CS and LDAC signals high (disabled)
wonner163 0:6e724cc2761b 50 int i;
wonner163 0:6e724cc2761b 51 for (i=0; i<_ndacs; i++) {
wonner163 0:6e724cc2761b 52 _ncs_array[i]->write(1);
wonner163 0:6e724cc2761b 53 }
wonner163 0:6e724cc2761b 54
wonner163 0:6e724cc2761b 55 if (_latched ) _nldac->write(1);
wonner163 0:6e724cc2761b 56 return;
wonner163 0:6e724cc2761b 57 }
wonner163 0:6e724cc2761b 58
wonner163 0:6e724cc2761b 59 // Set SPI clock frequency.
wonner163 0:6e724cc2761b 60 void MCP4922::frequency( int freq ) {
wonner163 0:6e724cc2761b 61
wonner163 0:6e724cc2761b 62 // Set the SPI interface clock frequency in Hz.
wonner163 0:6e724cc2761b 63 _spi.frequency( freq );
wonner163 0:6e724cc2761b 64 return;
wonner163 0:6e724cc2761b 65 }
wonner163 0:6e724cc2761b 66
wonner163 0:6e724cc2761b 67 /*
wonner163 0:6e724cc2761b 68 * Note: There is a lot of code in common between the following 4 functions.
wonner163 0:6e724cc2761b 69 * The code is kept in line to keep it efficient. Could the functions have
wonner163 0:6e724cc2761b 70 * been written as templates?
wonner163 0:6e724cc2761b 71 */
wonner163 0:6e724cc2761b 72 // Write to DAC channel A with gain 1.
wonner163 0:6e724cc2761b 73 void MCP4922::writeA(int value) {
wonner163 0:6e724cc2761b 74
wonner163 0:6e724cc2761b 75 // Set up the command register with the appropriate value.
wonner163 0:6e724cc2761b 76 // For efficiency, the caller is assumed to have checked dac.
wonner163 0:6e724cc2761b 77 int reg;
wonner163 0:6e724cc2761b 78 //int dac = 0;
wonner163 0:6e724cc2761b 79 reg = (value & 0x0FFF) | MCP4922_REG_A1;
wonner163 0:6e724cc2761b 80
wonner163 0:6e724cc2761b 81 // Select the DAC chip, write to its command register and
wonner163 0:6e724cc2761b 82 // then unselect the DAC chip.
wonner163 0:6e724cc2761b 83 _ncs_array[dac]->write(0);
wonner163 0:6e724cc2761b 84 _spi.write(reg);
wonner163 0:6e724cc2761b 85 _ncs_array[dac]->write(1);
wonner163 0:6e724cc2761b 86 return;
wonner163 0:6e724cc2761b 87 }
wonner163 0:6e724cc2761b 88
wonner163 0:6e724cc2761b 89 // Write to DAC channel B with gain 1.
wonner163 0:6e724cc2761b 90 void MCP4922::writeB(int value) {
wonner163 0:6e724cc2761b 91
wonner163 0:6e724cc2761b 92 // Set up the command register with the appropriate value.
wonner163 0:6e724cc2761b 93 // For efficiency, the caller is assumed to have checked dac.
wonner163 0:6e724cc2761b 94 int reg;
wonner163 0:6e724cc2761b 95 reg = (value & 0x0FFF) | MCP4922_REG_B1;
wonner163 0:6e724cc2761b 96
wonner163 0:6e724cc2761b 97 // Select the DAC chip, write to its command register and then
wonner163 0:6e724cc2761b 98 // unselect the DAC chip.
wonner163 0:6e724cc2761b 99 _ncs_array[dac]->write(0);
wonner163 0:6e724cc2761b 100 _spi.write(reg);
wonner163 0:6e724cc2761b 101 _ncs_array[dac]->write(1);
wonner163 0:6e724cc2761b 102 return;
wonner163 0:6e724cc2761b 103 }
wonner163 0:6e724cc2761b 104
wonner163 0:6e724cc2761b 105 // Write an array of values to the DACs.
wonner163 0:6e724cc2761b 106 void MCP4922::write(int nchans, int values[], int gain, int latch) {
wonner163 0:6e724cc2761b 107
wonner163 0:6e724cc2761b 108 // nchans must be at least 1 but less than or equal to ndacs x 2.
wonner163 0:6e724cc2761b 109 if (nchans < 1) nchans = 1;
wonner163 0:6e724cc2761b 110 const int maxchans = _ndacs * 2;
wonner163 0:6e724cc2761b 111 if (nchans > maxchans) nchans = maxchans;
wonner163 0:6e724cc2761b 112
wonner163 0:6e724cc2761b 113 if (latch && _latched)
wonner163 0:6e724cc2761b 114 latch_disable();
wonner163 0:6e724cc2761b 115
wonner163 0:6e724cc2761b 116 int i;
wonner163 0:6e724cc2761b 117
wonner163 0:6e724cc2761b 118 for (i=0; i<nchans;) {
wonner163 0:6e724cc2761b 119 dac = i/2;
wonner163 0:6e724cc2761b 120 writeA(values[i]);
wonner163 0:6e724cc2761b 121 i++;
wonner163 0:6e724cc2761b 122 if (i < nchans) {
wonner163 0:6e724cc2761b 123 writeB(values[i]);
wonner163 0:6e724cc2761b 124 i++;
wonner163 0:6e724cc2761b 125 } else break;
wonner163 0:6e724cc2761b 126 }
wonner163 0:6e724cc2761b 127
wonner163 0:6e724cc2761b 128 // Automatically latch the new voltages if the latch flag is 1.
wonner163 0:6e724cc2761b 129 if (latch && _latched)
wonner163 0:6e724cc2761b 130 latch_enable();
wonner163 0:6e724cc2761b 131 return;
wonner163 0:6e724cc2761b 132 }
wonner163 0:6e724cc2761b 133
wonner163 0:6e724cc2761b 134 // Set latch signal to "enable".
wonner163 0:6e724cc2761b 135 void MCP4922::latch_enable() {
wonner163 0:6e724cc2761b 136
wonner163 0:6e724cc2761b 137 // Latch all chips. There should be a delay of at least T_LS=40
wonner163 0:6e724cc2761b 138 // nanoseconds between the last CS rising edge and the LDAC falling
wonner163 0:6e724cc2761b 139 // edge. The software function calls seem to be sufficient to
wonner163 0:6e724cc2761b 140 // introduce that delay. A delay may be inserted here if this
wonner163 0:6e724cc2761b 141 // software is ported to a faster processor.
wonner163 0:6e724cc2761b 142 if (_latched) _nldac->write(0);
wonner163 0:6e724cc2761b 143 // The LDAC pulse width must be at least T_LD=100 nanoseconds long.
wonner163 0:6e724cc2761b 144 // A delay can be inserted here if necessary, but so far this has
wonner163 0:6e724cc2761b 145 // not been needed (see above).
wonner163 0:6e724cc2761b 146 return;
wonner163 0:6e724cc2761b 147 }
wonner163 0:6e724cc2761b 148
wonner163 0:6e724cc2761b 149 // Set latch signal to "disable".
wonner163 0:6e724cc2761b 150 void MCP4922::latch_disable() {
wonner163 0:6e724cc2761b 151
wonner163 0:6e724cc2761b 152 // Disable latch for all chips.
wonner163 0:6e724cc2761b 153 if (_latched) _nldac->write(1);
wonner163 0:6e724cc2761b 154 return;
wonner163 0:6e724cc2761b 155 }
wonner163 0:6e724cc2761b 156