A feature complete driver for the MCP4922 DAC from Microchip.

Dependents:   MCP4922_HelloWorld NuMidi401 NuFM401 NuFM402

Committer:
neilt6
Date:
Thu May 15 23:51:38 2014 +0000
Revision:
1:747ec9c5d80e
Parent:
0:e994c6963c66
Constructor now initializes the internal variables, and performs an initial write to make sure they're in sync

Who changed what in which revision?

UserRevisionLine numberNew contents of line
neilt6 0:e994c6963c66 1 /* MCP4922 Driver Library
neilt6 0:e994c6963c66 2 * Copyright (c) 2014 Neil Thiessen
neilt6 0:e994c6963c66 3 *
neilt6 0:e994c6963c66 4 * Licensed under the Apache License, Version 2.0 (the "License");
neilt6 0:e994c6963c66 5 * you may not use this file except in compliance with the License.
neilt6 0:e994c6963c66 6 * You may obtain a copy of the License at
neilt6 0:e994c6963c66 7 *
neilt6 0:e994c6963c66 8 * http://www.apache.org/licenses/LICENSE-2.0
neilt6 0:e994c6963c66 9 *
neilt6 0:e994c6963c66 10 * Unless required by applicable law or agreed to in writing, software
neilt6 0:e994c6963c66 11 * distributed under the License is distributed on an "AS IS" BASIS,
neilt6 0:e994c6963c66 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
neilt6 0:e994c6963c66 13 * See the License for the specific language governing permissions and
neilt6 0:e994c6963c66 14 * limitations under the License.
neilt6 0:e994c6963c66 15 */
neilt6 0:e994c6963c66 16
neilt6 0:e994c6963c66 17 #include "MCP4922.h"
neilt6 0:e994c6963c66 18
neilt6 0:e994c6963c66 19 MCP4922::MCP4922(PinName mosi, PinName sclk, PinName cs, int hz) : m_SPI(mosi, NC, sclk), m_CS(cs, 1)
neilt6 0:e994c6963c66 20 {
neilt6 1:747ec9c5d80e 21 //Initialize the member variables
neilt6 1:747ec9c5d80e 22 m_DacValueA = 0;
neilt6 1:747ec9c5d80e 23 m_DacValueB = 0;
neilt6 1:747ec9c5d80e 24
neilt6 0:e994c6963c66 25 //Set the SPI format and bus frequency
neilt6 0:e994c6963c66 26 m_SPI.format(16, 0);
neilt6 0:e994c6963c66 27 m_SPI.frequency(hz);
neilt6 1:747ec9c5d80e 28
neilt6 1:747ec9c5d80e 29 //Perform an initial write to both DACs so the variables are in sync
neilt6 1:747ec9c5d80e 30 writeDac(m_DacValueA | (DAC_A << 15));
neilt6 1:747ec9c5d80e 31 writeDac(m_DacValueB | (DAC_B << 15));
neilt6 0:e994c6963c66 32 }
neilt6 0:e994c6963c66 33
neilt6 0:e994c6963c66 34 MCP4922::ReferenceMode MCP4922::referenceMode(DAC dac)
neilt6 0:e994c6963c66 35 {
neilt6 0:e994c6963c66 36 //Return the current reference mode for the specified DAC
neilt6 0:e994c6963c66 37 if (dac == DAC_A)
neilt6 0:e994c6963c66 38 return (ReferenceMode)((m_DacValueA >> 14) & 0x01);
neilt6 0:e994c6963c66 39 else
neilt6 0:e994c6963c66 40 return (ReferenceMode)((m_DacValueB >> 14) & 0x01);
neilt6 0:e994c6963c66 41 }
neilt6 0:e994c6963c66 42
neilt6 0:e994c6963c66 43 void MCP4922::referenceMode(DAC dac, ReferenceMode mode)
neilt6 0:e994c6963c66 44 {
neilt6 0:e994c6963c66 45 //Update the reference mode for the specified DAC
neilt6 0:e994c6963c66 46 if (dac == DAC_A) {
neilt6 0:e994c6963c66 47 //Mask off the old mode, and set the new one
neilt6 0:e994c6963c66 48 m_DacValueA &= ~(1 << 14);
neilt6 0:e994c6963c66 49 m_DacValueA |= (mode << 14);
neilt6 0:e994c6963c66 50
neilt6 0:e994c6963c66 51 //Update the DAC A
neilt6 0:e994c6963c66 52 writeDac(m_DacValueA | (dac << 15));
neilt6 0:e994c6963c66 53 } else {
neilt6 0:e994c6963c66 54 //Mask off the old mode, and set the new one
neilt6 0:e994c6963c66 55 m_DacValueB &= ~(1 << 14);
neilt6 0:e994c6963c66 56 m_DacValueB |= (mode << 14);
neilt6 0:e994c6963c66 57
neilt6 0:e994c6963c66 58 //Update the DAC B
neilt6 0:e994c6963c66 59 writeDac(m_DacValueB | (dac << 15));
neilt6 0:e994c6963c66 60 }
neilt6 0:e994c6963c66 61 }
neilt6 0:e994c6963c66 62
neilt6 0:e994c6963c66 63 MCP4922::GainMode MCP4922::gainMode(DAC dac)
neilt6 0:e994c6963c66 64 {
neilt6 0:e994c6963c66 65 //Return the current gain mode for the specified DAC
neilt6 0:e994c6963c66 66 if (dac == DAC_A)
neilt6 0:e994c6963c66 67 return (GainMode)((m_DacValueA >> 13) & 0x01);
neilt6 0:e994c6963c66 68 else
neilt6 0:e994c6963c66 69 return (GainMode)((m_DacValueB >> 13) & 0x01);
neilt6 0:e994c6963c66 70 }
neilt6 0:e994c6963c66 71
neilt6 0:e994c6963c66 72 void MCP4922::gainMode(DAC dac, GainMode mode)
neilt6 0:e994c6963c66 73 {
neilt6 0:e994c6963c66 74 //Update the gain mode for the specified DAC
neilt6 0:e994c6963c66 75 if (dac == DAC_A) {
neilt6 0:e994c6963c66 76 //Mask off the old mode, and set the new one
neilt6 0:e994c6963c66 77 m_DacValueA &= ~(1 << 13);
neilt6 0:e994c6963c66 78 m_DacValueA |= (mode << 13);
neilt6 0:e994c6963c66 79
neilt6 0:e994c6963c66 80 //Update the DAC A
neilt6 0:e994c6963c66 81 writeDac(m_DacValueA | (dac << 15));
neilt6 0:e994c6963c66 82 } else {
neilt6 0:e994c6963c66 83 //Mask off the old mode, and set the new one
neilt6 0:e994c6963c66 84 m_DacValueB &= ~(1 << 13);
neilt6 0:e994c6963c66 85 m_DacValueB |= (mode << 13);
neilt6 0:e994c6963c66 86
neilt6 0:e994c6963c66 87 //Update the DAC B
neilt6 0:e994c6963c66 88 writeDac(m_DacValueB | (dac << 15));
neilt6 0:e994c6963c66 89 }
neilt6 0:e994c6963c66 90 }
neilt6 0:e994c6963c66 91
neilt6 0:e994c6963c66 92 MCP4922::PowerMode MCP4922::powerMode(DAC dac)
neilt6 0:e994c6963c66 93 {
neilt6 0:e994c6963c66 94 //Return the current power mode for the specified DAC
neilt6 0:e994c6963c66 95 if (dac == DAC_A)
neilt6 0:e994c6963c66 96 return (PowerMode)((m_DacValueA >> 12) & 0x01);
neilt6 0:e994c6963c66 97 else
neilt6 0:e994c6963c66 98 return (PowerMode)((m_DacValueB >> 12) & 0x01);
neilt6 0:e994c6963c66 99 }
neilt6 0:e994c6963c66 100
neilt6 0:e994c6963c66 101 void MCP4922::powerMode(DAC dac, PowerMode mode)
neilt6 0:e994c6963c66 102 {
neilt6 0:e994c6963c66 103 //Update the power mode for the specified DAC
neilt6 0:e994c6963c66 104 if (dac == DAC_A) {
neilt6 0:e994c6963c66 105 //Mask off the old mode, and set the new one
neilt6 0:e994c6963c66 106 m_DacValueA &= ~(1 << 12);
neilt6 0:e994c6963c66 107 m_DacValueA |= (mode << 12);
neilt6 0:e994c6963c66 108
neilt6 0:e994c6963c66 109 //Update the DAC A
neilt6 0:e994c6963c66 110 writeDac(m_DacValueA | (dac << 15));
neilt6 0:e994c6963c66 111 } else {
neilt6 0:e994c6963c66 112 //Mask off the old mode, and set the new one
neilt6 0:e994c6963c66 113 m_DacValueB &= ~(1 << 12);
neilt6 0:e994c6963c66 114 m_DacValueB |= (mode << 12);
neilt6 0:e994c6963c66 115
neilt6 0:e994c6963c66 116 //Update the DAC B
neilt6 0:e994c6963c66 117 writeDac(m_DacValueB | (dac << 15));
neilt6 0:e994c6963c66 118 }
neilt6 0:e994c6963c66 119 }
neilt6 0:e994c6963c66 120
neilt6 0:e994c6963c66 121 float MCP4922::read(DAC dac)
neilt6 0:e994c6963c66 122 {
neilt6 0:e994c6963c66 123 //Return the current value for the specified DAC as a float
neilt6 0:e994c6963c66 124 if (dac == DAC_A)
neilt6 0:e994c6963c66 125 return (m_DacValueA & 0x0FFF) / 4095.0;
neilt6 0:e994c6963c66 126 else
neilt6 0:e994c6963c66 127 return (m_DacValueB & 0x0FFF) / 4095.0;
neilt6 0:e994c6963c66 128 }
neilt6 0:e994c6963c66 129
neilt6 0:e994c6963c66 130 void MCP4922::write(DAC dac, float value)
neilt6 0:e994c6963c66 131 {
neilt6 0:e994c6963c66 132 //Range limit value
neilt6 0:e994c6963c66 133 if (value < 0.0)
neilt6 0:e994c6963c66 134 value = 0.0;
neilt6 0:e994c6963c66 135 else if (value > 1.0)
neilt6 0:e994c6963c66 136 value = 1.0;
neilt6 0:e994c6963c66 137
neilt6 0:e994c6963c66 138 //Convert value to an unsigned short, and pass it to write_u16()
neilt6 0:e994c6963c66 139 write_u16(dac, (unsigned short)(value * 4095) << 4);
neilt6 0:e994c6963c66 140 }
neilt6 0:e994c6963c66 141
neilt6 0:e994c6963c66 142 void MCP4922::write_u16(DAC dac, unsigned short value)
neilt6 0:e994c6963c66 143 {
neilt6 0:e994c6963c66 144 //Update the value for the specified DAC
neilt6 0:e994c6963c66 145 if (dac == DAC_A) {
neilt6 0:e994c6963c66 146 //Mask off the old value, and set the new one
neilt6 0:e994c6963c66 147 m_DacValueA &= 0xF000;
neilt6 0:e994c6963c66 148 m_DacValueA |= value >> 4;
neilt6 0:e994c6963c66 149
neilt6 0:e994c6963c66 150 //Update the DAC A
neilt6 0:e994c6963c66 151 writeDac(m_DacValueA | (dac << 15));
neilt6 0:e994c6963c66 152 } else {
neilt6 0:e994c6963c66 153 //Mask off the old value, and set the new one
neilt6 0:e994c6963c66 154 m_DacValueB &= 0xF000;
neilt6 0:e994c6963c66 155 m_DacValueB |= value >> 4;
neilt6 0:e994c6963c66 156
neilt6 0:e994c6963c66 157 //Update the DAC B
neilt6 0:e994c6963c66 158 writeDac(m_DacValueB | (dac << 15));
neilt6 0:e994c6963c66 159 }
neilt6 0:e994c6963c66 160 }
neilt6 0:e994c6963c66 161
neilt6 0:e994c6963c66 162 void MCP4922::writeDac(unsigned short value)
neilt6 0:e994c6963c66 163 {
neilt6 0:e994c6963c66 164 //Pull CS low
neilt6 0:e994c6963c66 165 m_CS = 0;
neilt6 0:e994c6963c66 166
neilt6 0:e994c6963c66 167 //Perform the 16-bit write
neilt6 0:e994c6963c66 168 m_SPI.write(value);
neilt6 0:e994c6963c66 169
neilt6 0:e994c6963c66 170 //Pull CS high
neilt6 0:e994c6963c66 171 m_CS = 1;
neilt6 0:e994c6963c66 172 }