Lab5

Dependencies:   mbed

Committer:
Supermil
Date:
Tue Nov 21 16:17:32 2017 +0000
Revision:
0:59a8574b663a
lab6 MCP4922;

Who changed what in which revision?

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