Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: MCP4822.cpp
- Revision:
- 2:2b1457f78377
- Parent:
- 1:f3de66b30fc3
--- a/MCP4822.cpp Thu Feb 25 12:18:14 2021 +0000 +++ b/MCP4822.cpp Thu Feb 25 13:50:05 2021 +0000 @@ -1,3 +1,247 @@ +/* MCP4922 Driver Library + * Copyright (c) 2014 Neil Thiessen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "MCP4822.h" + +#define SPI_16_BITS 0 +#define SPI_8_BITS 1 + + +MCP4922::MCP4922(PinName mosi, PinName miso, PinName sclk, PinName cs, int hz) : m_SPI(mosi, miso, sclk), m_CS(cs, 1) +{ + //Initialize the member variables + m_DacValueA = 0; + m_DacValueB = 0; + + //Set the SPI format and bus frequency + #if SPI_16_BITS + m_SPI.format(16, 0); + #endif + + #if SPI_8_BITS + m_SPI.format(8, 0); + #endif + + m_SPI.frequency(hz); + + //Perform an initial write to both DACs so the variables are in sync + writeDac(m_DacValueA | (DAC_A << 15)); + writeDac(m_DacValueB | (DAC_B << 15)); +} + +MCP4922::ReferenceMode MCP4922::referenceMode(DAC dac) +{ + //Return the current reference mode for the specified DAC + if (dac == DAC_A) + return (ReferenceMode)((m_DacValueA >> 14) & 0x01); + else + return (ReferenceMode)((m_DacValueB >> 14) & 0x01); +} + +void MCP4922::referenceMode(DAC dac, ReferenceMode mode) +{ + //Update the reference mode for the specified DAC + if (dac == DAC_A) { + //Mask off the old mode, and set the new one + m_DacValueA &= ~(1 << 14); + m_DacValueA |= (mode << 14); + + //Update the DAC A + writeDac(m_DacValueA | (dac << 15)); + } else { + //Mask off the old mode, and set the new one + m_DacValueB &= ~(1 << 14); + m_DacValueB |= (mode << 14); + + //Update the DAC B + writeDac(m_DacValueB | (dac << 15)); + } +} + +MCP4922::GainMode MCP4922::gainMode(DAC dac) +{ + //Return the current gain mode for the specified DAC + if (dac == DAC_A) + return (GainMode)((m_DacValueA >> 13) & 0x01); + else + return (GainMode)((m_DacValueB >> 13) & 0x01); +} + +void MCP4922::gainMode(DAC dac, GainMode mode) +{ + //Update the gain mode for the specified DAC + if (dac == DAC_A) { + //Mask off the old mode, and set the new one + m_DacValueA &= ~(1 << 13); + m_DacValueA |= (mode << 13); + + //Update the DAC A + writeDac(m_DacValueA | (dac << 15)); + } else { + //Mask off the old mode, and set the new one + m_DacValueB &= ~(1 << 13); + m_DacValueB |= (mode << 13); + + //Update the DAC B + writeDac(m_DacValueB | (dac << 15)); + } +} + +MCP4922::PowerMode MCP4922::powerMode(DAC dac) +{ + //Return the current power mode for the specified DAC + if (dac == DAC_A) + return (PowerMode)((m_DacValueA >> 12) & 0x01); + else + return (PowerMode)((m_DacValueB >> 12) & 0x01); +} + +void MCP4922::powerMode(DAC dac, PowerMode mode) +{ + //Update the power mode for the specified DAC + if (dac == DAC_A) { + //Mask off the old mode, and set the new one + m_DacValueA &= ~(1 << 12); + m_DacValueA |= (mode << 12); + + //Update the DAC A + writeDac(m_DacValueA | (dac << 15)); + } else { + //Mask off the old mode, and set the new one + m_DacValueB &= ~(1 << 12); + m_DacValueB |= (mode << 12); + + //Update the DAC B + writeDac(m_DacValueB | (dac << 15)); + } +} + +float MCP4922::read(DAC dac) +{ + //Return the current value for the specified DAC as a float + if (dac == DAC_A) + return (m_DacValueA & 0x0FFF) / 4095.0; + else + return (m_DacValueB & 0x0FFF) / 4095.0; +} +uint16_t MCP4922::read_u16(DAC dac){ + + //Return the current value for the specified DAC as a float + if (dac == DAC_A) + return m_DacValueA; + else + return m_DacValueB; +} + +void MCP4922::write(DAC dac, float value) +{ + //Range limit value + if (value < 0.00f) + value = 0.00f; + else if (value > 1.00f) + value = 1.00f; + + //Convert value to an unsigned short, and pass it to write_u16() + write_u16(dac, (unsigned short)(value * 4095) << 4); +} + +void MCP4922::write_u16(DAC dac, uint16_t value) +{ + //Update the value for the specified DAC + if (dac == DAC_A) { + //Mask off the old value, and set the new one + m_DacValueA &= 0xF000; + m_DacValueA |= value >> 4; + + //Update the DAC A + writeDac(m_DacValueA | (dac << 15)); + } else { + //Mask off the old value, and set the new one + m_DacValueB &= 0xF000; + m_DacValueB |= value >> 4; + + //Update the DAC B + writeDac(m_DacValueB | (dac << 15)); + } +} + +void MCP4922::write_bits(DAC dac, uint16_t value) +{ + if (dac == DAC_A) { + write_DAC_A(value); + } + else{ + write_DAC_B(value); + } +} + +// DAC A : +// avec GAIN x2 etc pour le CV +void MCP4922::write_DAC_A(uint16_t value){ + // on clip : + if( value > 0x0FFF ){ + value = 0x0FFF; + } + // DAC A : + // si unbuffered : 0001 0x1000 + // si buffered : 0101 0x5000 + writeDac( 0x1000 | value ); // unbuffered + //writeDac( 0x5000 | value ); // buffered + +} + + // DAC B : +void MCP4922::write_DAC_B(uint16_t value){ + // on clip : + if( value > 0x0FFF ){ + value = 0x0FFF; + } + + // DAC B : + // si unbuffered : 1001 0x9000 + // si buffered : 1101 0xD000 + writeDac( 0x9000 | value ); // unbuffered + //writeDac( 0xD000 | value ); // buffered + +} + +void MCP4922::writeDac(unsigned short value) +{ + //Pull CS low + m_CS = 0; + + //Perform the 16-bit write + #if SPI_16_BITS + m_SPI.write(value); + #endif + + #if SPI_8_BITS + m_SPI.write( value >> 8 ); + m_SPI.write( value & 0xFF); + #endif + + //Pull CS high + m_CS = 1; +} + + + + + +#if 0 /* mbed MCP4822 Library, for driving the 12-Bit DAC with internal Vref and SPI interface * Copyright (c) 2015, Created by Steen Joergensen (stjo2809) * @@ -116,4 +360,6 @@ _spi.write(_upper_half); _spi.write(_lower_half); _nCs = 1; - } \ No newline at end of file + } + +#endif \ No newline at end of file