benoit poulain / MCP4822_mod
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