labSPI

Dependencies:   mbed

Fork of MCP4922_Sinewave by FRA221_2015

Committer:
jf1vrr
Date:
Wed May 11 12:04:37 2011 +0000
Revision:
0:5737b1972549
Ver. 0.01A New 2011/05/11

Who changed what in which revision?

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