Simplified access to a Microchip Digital Potentiometer (MCP41xxx/MCP42xxx) devices

Dependents:   MCP41xxxApp MCP320xApp MCP41xxxApp

Files at this revision

API Documentation at this revision

Comitter:
Yann
Date:
Fri Jan 25 16:10:58 2013 +0000
Child:
1:cf3cee91eb87
Commit message:
Create library and test application to support Microchip Digital Potentiometers MCP42xxx/MCP41xxx

Changed in this revision

MCP4xxxx_SPI.cpp Show annotated file Show diff for this revision Revisions of this file
MCP4xxxx_SPI.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MCP4xxxx_SPI.cpp	Fri Jan 25 16:10:58 2013 +0000
@@ -0,0 +1,143 @@
+/* mbed simplified access to Microchip 24LCxx Serial EEPROM devices (SPI)
+ * Copyright (c) 2010-2012 ygarcia, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
+ * and associated documentation files (the "Software"), to deal in the Software without restriction, 
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or 
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "MCP4xxxx_SPI.h"
+
+namespace MCP4xxxx_SPI {
+
+    unsigned char CMCP4xxxx_SPI::SPIModuleRefCounter = 0;
+
+    CMCP4xxxx_SPI::CMCP4xxxx_SPI(const PinName p_mosi, const PinName p_miso, const PinName p_sclk, const PinName p_reset, const PinName p_shdn, const unsigned int p_frequency) : _internalId("") {
+        DEBUG_ENTER("CMCP4xxxx_SPI")
+
+        if (CMCP4xxxx_SPI::SPIModuleRefCounter != 0) {
+            error("CMCP4xxxx_SPI: Wrong params");
+        }
+
+        _spiInstance = new SPI(p_mosi, p_miso, p_sclk);
+        _spiInstance->frequency(p_frequency); // Set the frequency of the SPI interface
+        _spiInstance->format(16, 0); // See http://mbed.org/users/mbed_official/code/mbed/docs/0954ebd79f59//classmbed_1_1SPI.html
+        CMCP4xxxx_SPI::SPIModuleRefCounter += 1;
+        DEBUG_ENTER("CMCP4xxxx_SPI: refCounter=%d", CMCP4xxxx_SPI::SPIModuleRefCounter)
+
+        if (p_reset != NC) {
+            DEBUG("CMCP4xxxx_SPI: /RESET managed");
+            _reset = new DigitalOut(p_reset);
+            _reset->write(1); // Disable reset
+        } else {
+            DEBUG("CMCP4xxxx_SPI: /RESET not managed");
+            _reset = NULL; // Not used
+        }
+    
+        if (p_shdn != NC) {
+            DEBUG("CMCP4xxxx_SPI: /SHDN managed");
+            _shdn = new DigitalOut(p_shdn);
+            _shdn->write(1); // Disable shutdown
+        } else {
+            DEBUG("CMCP4xxxx_SPI: /SHDN not managed");
+            _shdn = NULL; // Not used
+        }
+    
+        DEBUG_LEAVE("CMCP4xxxx_SPI")
+    }
+
+    CMCP4xxxx_SPI::~CMCP4xxxx_SPI() {
+        DEBUG_ENTER("~CMCP4xxxx_SPI")
+    
+        // Release I2C instance
+        DEBUG_ENTER("~CMCP4xxxx_SPI: refCounter=%d", CMCP4xxxx_SPI::SPIModuleRefCounter)
+        CMCP4xxxx_SPI::SPIModuleRefCounter -= 1;
+        if (CMCP4xxxx_SPI::SPIModuleRefCounter == 0) {
+            delete _spiInstance;
+            _spiInstance = NULL;
+        }
+        // Release _reset if required
+        if (_reset != NULL) {
+            _reset->write(0);
+            delete _reset;
+        }
+         // Release _shdn if required
+        if (_shdn != NULL) {
+            _shdn->write(0);
+            delete _shdn;
+        }
+   
+        DEBUG_LEAVE("~CMCP4xxxx_SPI")
+    }
+    
+    unsigned short CMCP4xxxx_SPI::Write(const Commands p_command, const unsigned char p_value) {
+        DEBUG_ENTER("CMCP4xxxx_SPI::Write: 0x%02x - 0x%02x", (unsigned char)p_command, p_value)
+        
+        unsigned short command = 0;
+        switch (p_command) {
+            case WriteToPot1: 
+                command = (0x11 << 8 | p_value);
+                break;
+            case WriteToPot2:
+                command = (0x12 << 8 | p_value);
+                break;
+            case WriteToPotBoth:
+                command = (0x13 << 8 | p_value);
+                break;
+            case ShutdownPot1:
+                command = (0x21 << 8);
+                break;
+            case ShutdownPot2:
+                command = (0x21 << 8);
+                break;
+            default: //<! Shutdown both digital potentiometers
+                command = (0x23 << 8);                
+        } // End of 'switch' statement
+        
+        DEBUG("CMCP4xxxx_SPI: Send command: 0x%04x", command)
+        unsigned short result = _spiInstance->write(command);
+        
+        DEBUG_LEAVE("CMCP4xxxx_SPI::Write: %d", result)
+        return result;
+    }
+
+    unsigned short CMCP4xxxx_SPI::Write() {
+        return _spiInstance->write(0);
+    }
+
+    bool CMCP4xxxx_SPI::Reset() {
+        // Sanity check
+        if (_reset == NULL) {
+            return false;
+        }
+        
+        _reset->write(0); // Set level low to activate reset 
+        wait_us(1); // Wait for 1us
+         _reset->write(1); // Set level low to de-activate reset 
+       
+        return true;
+    }
+    
+    bool CMCP4xxxx_SPI::Shutdown(const bool p_set) {
+        // Sanity check
+        if (_shdn == NULL) {
+            return false;
+        }
+        
+        _shdn->write(p_set == false ? 0 : 1);
+        
+        return true;
+    }
+
+} // End of namespace MCP4xxxx_SPI
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MCP4xxxx_SPI.h	Fri Jan 25 16:10:58 2013 +0000
@@ -0,0 +1,123 @@
+/* mbed simplified access to Microchip MCP42xxx/MCP41xxx Digital Potentiometer devices (SPI)
+ * Copyright (c) 2013-2013 ygarcia, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
+ * and associated documentation files (the "Software"), to deal in the Software without restriction, 
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or 
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#if !defined(__MCP4xxxx_SPI_H__)
+#define __MCP4xxxx_SPI_H__
+
+#include <string>
+#include <vector>
+
+#include "Debug.h" // Include mbed header + debug primitives. See DebugLibrary
+
+namespace MCP4xxxx_SPI {
+
+    /** This class provides simplified SPI access to a Microchip MCP42xxx/MCP41xxx Digital Potentiometer device. V0.0.0.1
+     * This class DOES NOT manage /CS pin. It shall be done by the application itself
+     *
+     * Microchip MCP42xxx/MCP41xxx Serial EEPROM device reference: DS11195C
+     *
+     * Note that for SPI details, please visit http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
+     *
+     * @remark This class was validated with Tektronix TDS2014 oscilloscope in 3.3V and in mixte power mode 3.3V for mbed and 5V for the Microchip 24LCxx Serial EEPROM device
+     * @author Yann Garcia (Don't hesitate to contact me: garcia.yann@gmail.com)
+     */
+    class CMCP4xxxx_SPI { 
+        /** Reference counter used to guarentee unicity of the instance of SPI class
+         */
+        static unsigned char SPIModuleRefCounter;
+        
+        /** Reset state indicator (pin 11); true to reset device, false otherwise (DS11195C-page 21 Clause 5.5 Reset (RS) Pin Operation)
+         */
+        DigitalOut *_reset;
+        /** Shutdown state indicator (pin 12); true to shutdown device, false otherwise (DS11195C-page 21 5.6 Shutdown (SHDN) Pin Operation)
+         */
+        DigitalOut *_shdn;
+        /** An unique instance of SPI class
+         */
+        SPI *_spiInstance;
+     public:
+        /** Authorized commands
+         * See DS11195C-page 18
+         */
+        enum Commands {
+            WriteToPot1, //<! Write to digital potentiometer #1
+            WriteToPot2, //<! Write to digital potentiometer #2
+            WriteToPotBoth, //<! Write to both digital potentiometers
+            ShutdownPot1, //<! Shutdown digital potentiometer #1
+            ShutdownPot2, //<! Shutdown digital potentiometer #2
+            ShutdownPotBoth, //<! Shutdown both digital potentiometers
+        };
+   public:
+        /** Constructor with Write Protect command pin wired.
+         *
+         * @param p_mosi: MBed pin for SDI
+         * @param p_miso: MBed pin for SDO. Note that this pin does not exist for MCP41xxx
+         * @param p_sclk: MBed pin for CLK
+         * @param p_reset: MBed pin to manage /RESET input. If NC, /RESET is not managed, default value is NC, not connected
+         * @param p_shdn: MBed pin to manage /SHDN input. If NC, /SHDN is not managed, default value is NC, not connected
+         * @param p_frequency: Frequency of the SPI interface (SCK), default value is 1MHz
+         */
+        CMCP4xxxx_SPI(const PinName p_mosi, const PinName p_miso, const PinName p_sclk, const PinName p_reset = NC, const PinName p_shdn = NC, const unsigned int p_frequency = 1000000);
+    
+        /** Destructor
+         */
+        virtual ~CMCP4xxxx_SPI();
+
+        /** Used to return the unique instance of SPI instance
+         */
+        inline const SPI * operator * () { return (const SPI *)_spiInstance; };
+
+        /** Write a command
+         *
+         * @param p_command The command to execute: Write or Shutdown (See DS11195C-page 18)
+         * @param p_value The potentiometer selection bits (See DS11195C-page 14 Clause 4.1 Modes of Operation)
+         * @return true on success, false otherwise
+         * Exemple:
+         * @code
+         * unsigned char value = 0xaa;
+         * ...
+         * myEEPROM.Write(memoryAddress, value);
+         * ...
+         * @endcode
+         */
+        unsigned short Write(const Commands p_command, const unsigned char p_value);
+    
+         /** Write a NOP command
+         */
+        unsigned short Write();
+    
+       /** Reset the device
+         */
+        bool Reset();
+    
+        /** Shutdown the device
+         */
+        bool Shutdown(const bool p_set);
+    
+    private:
+        /** Internal reference identifier
+         */
+        std::string _internalId;
+
+    }; // End of class CMCP4xxxx_SPI
+
+} // End of namespace MCP4xxxx_SPI
+
+using namespace MCP4xxxx_SPI;
+
+#endif // __MCP4xxxx_SPI_H__