This is a program to output a sinwave in 12 bits Digital to Analog converter MCP4922. Sampling frequency is 166,667Hz and produce an interrupt of Ticker every 6uS. The Program calculates the data of the sinewave beforehand.

Dependencies:   TextLCD mbed

Committer:
jf1vrr
Date:
Thu May 12 11:12:47 2011 +0000
Revision:
1:09b69f38fc73
Parent:
0:5737b1972549
Rev, 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