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

Dependents:   MCP41xxxApp MCP320xApp MCP41xxxApp

Committer:
Yann
Date:
Mon Feb 04 17:15:33 2013 +0000
Revision:
4:bbfc8e352ff5
Parent:
2:7c27fb9785be
Child:
5:4f6133144e7e
Change wrong comments

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Yann 4:bbfc8e352ff5 1 /* mbed simplified access to Microchip MCP42xxx/MCP41xxx Digital Potentiometer devices (SPI)
Yann 1:cf3cee91eb87 2 * Copyright (c) 2013 ygarcia, MIT License
Yann 0:03314ad622d6 3 *
Yann 0:03314ad622d6 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
Yann 0:03314ad622d6 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
Yann 0:03314ad622d6 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
Yann 0:03314ad622d6 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Yann 0:03314ad622d6 8 * furnished to do so, subject to the following conditions:
Yann 0:03314ad622d6 9 *
Yann 0:03314ad622d6 10 * The above copyright notice and this permission notice shall be included in all copies or
Yann 0:03314ad622d6 11 * substantial portions of the Software.
Yann 0:03314ad622d6 12 *
Yann 0:03314ad622d6 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
Yann 0:03314ad622d6 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Yann 0:03314ad622d6 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
Yann 0:03314ad622d6 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Yann 0:03314ad622d6 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Yann 0:03314ad622d6 18 */
Yann 0:03314ad622d6 19
Yann 0:03314ad622d6 20 #include "MCP4xxxx_SPI.h"
Yann 0:03314ad622d6 21
Yann 0:03314ad622d6 22 namespace MCP4xxxx_SPI {
Yann 0:03314ad622d6 23
Yann 0:03314ad622d6 24 unsigned char CMCP4xxxx_SPI::SPIModuleRefCounter = 0;
Yann 0:03314ad622d6 25
Yann 2:7c27fb9785be 26 CMCP4xxxx_SPI::CMCP4xxxx_SPI(const PinName p_mosi, const PinName p_miso, const PinName p_sclk, const PinName p_cs, const PinName p_reset, const PinName p_shdn, const unsigned int p_frequency) : _internalId("") {
Yann 0:03314ad622d6 27 DEBUG_ENTER("CMCP4xxxx_SPI")
Yann 0:03314ad622d6 28
Yann 4:bbfc8e352ff5 29 CMCP4xxxx_SPI::SPIModuleRefCounter += 1;
Yann 4:bbfc8e352ff5 30 if (CMCP4xxxx_SPI::SPIModuleRefCounter > 1) {
Yann 4:bbfc8e352ff5 31 // Nothing to do
Yann 4:bbfc8e352ff5 32 return;
Yann 0:03314ad622d6 33 }
Yann 0:03314ad622d6 34
Yann 0:03314ad622d6 35 _spiInstance = new SPI(p_mosi, p_miso, p_sclk);
Yann 0:03314ad622d6 36 _spiInstance->frequency(p_frequency); // Set the frequency of the SPI interface
Yann 0:03314ad622d6 37 _spiInstance->format(16, 0); // See http://mbed.org/users/mbed_official/code/mbed/docs/0954ebd79f59//classmbed_1_1SPI.html
Yann 0:03314ad622d6 38 DEBUG_ENTER("CMCP4xxxx_SPI: refCounter=%d", CMCP4xxxx_SPI::SPIModuleRefCounter)
Yann 0:03314ad622d6 39
Yann 2:7c27fb9785be 40 if (p_cs != NC) {
Yann 2:7c27fb9785be 41 DEBUG("CMCP4xxxx_SPI: /CS managed");
Yann 2:7c27fb9785be 42 _cs = new DigitalOut(p_cs);
Yann 2:7c27fb9785be 43 _cs->write(1); // Disable chip
Yann 2:7c27fb9785be 44 } else {
Yann 2:7c27fb9785be 45 DEBUG("CMCP4xxxx_SPI: /CS not managed");
Yann 2:7c27fb9785be 46 _cs = NULL; // Not used
Yann 2:7c27fb9785be 47 }
Yann 2:7c27fb9785be 48
Yann 0:03314ad622d6 49 if (p_reset != NC) {
Yann 0:03314ad622d6 50 DEBUG("CMCP4xxxx_SPI: /RESET managed");
Yann 0:03314ad622d6 51 _reset = new DigitalOut(p_reset);
Yann 0:03314ad622d6 52 _reset->write(1); // Disable reset
Yann 0:03314ad622d6 53 } else {
Yann 0:03314ad622d6 54 DEBUG("CMCP4xxxx_SPI: /RESET not managed");
Yann 0:03314ad622d6 55 _reset = NULL; // Not used
Yann 0:03314ad622d6 56 }
Yann 0:03314ad622d6 57
Yann 0:03314ad622d6 58 if (p_shdn != NC) {
Yann 0:03314ad622d6 59 DEBUG("CMCP4xxxx_SPI: /SHDN managed");
Yann 0:03314ad622d6 60 _shdn = new DigitalOut(p_shdn);
Yann 0:03314ad622d6 61 _shdn->write(1); // Disable shutdown
Yann 0:03314ad622d6 62 } else {
Yann 0:03314ad622d6 63 DEBUG("CMCP4xxxx_SPI: /SHDN not managed");
Yann 0:03314ad622d6 64 _shdn = NULL; // Not used
Yann 0:03314ad622d6 65 }
Yann 0:03314ad622d6 66
Yann 0:03314ad622d6 67 DEBUG_LEAVE("CMCP4xxxx_SPI")
Yann 0:03314ad622d6 68 }
Yann 0:03314ad622d6 69
Yann 0:03314ad622d6 70 CMCP4xxxx_SPI::~CMCP4xxxx_SPI() {
Yann 0:03314ad622d6 71 DEBUG_ENTER("~CMCP4xxxx_SPI")
Yann 0:03314ad622d6 72
Yann 0:03314ad622d6 73 // Release I2C instance
Yann 0:03314ad622d6 74 DEBUG_ENTER("~CMCP4xxxx_SPI: refCounter=%d", CMCP4xxxx_SPI::SPIModuleRefCounter)
Yann 0:03314ad622d6 75 CMCP4xxxx_SPI::SPIModuleRefCounter -= 1;
Yann 0:03314ad622d6 76 if (CMCP4xxxx_SPI::SPIModuleRefCounter == 0) {
Yann 0:03314ad622d6 77 delete _spiInstance;
Yann 0:03314ad622d6 78 _spiInstance = NULL;
Yann 0:03314ad622d6 79 }
Yann 0:03314ad622d6 80 // Release _reset if required
Yann 2:7c27fb9785be 81 if (_cs != NULL) {
Yann 2:7c27fb9785be 82 _cs->write(0);
Yann 2:7c27fb9785be 83 delete _cs;
Yann 2:7c27fb9785be 84 }
Yann 2:7c27fb9785be 85 // Release _reset if required
Yann 0:03314ad622d6 86 if (_reset != NULL) {
Yann 0:03314ad622d6 87 _reset->write(0);
Yann 0:03314ad622d6 88 delete _reset;
Yann 0:03314ad622d6 89 }
Yann 2:7c27fb9785be 90 // Release _shdn if required
Yann 0:03314ad622d6 91 if (_shdn != NULL) {
Yann 0:03314ad622d6 92 _shdn->write(0);
Yann 0:03314ad622d6 93 delete _shdn;
Yann 0:03314ad622d6 94 }
Yann 0:03314ad622d6 95
Yann 0:03314ad622d6 96 DEBUG_LEAVE("~CMCP4xxxx_SPI")
Yann 0:03314ad622d6 97 }
Yann 0:03314ad622d6 98
Yann 0:03314ad622d6 99 unsigned short CMCP4xxxx_SPI::Write(const Commands p_command, const unsigned char p_value) {
Yann 0:03314ad622d6 100 DEBUG_ENTER("CMCP4xxxx_SPI::Write: 0x%02x - 0x%02x", (unsigned char)p_command, p_value)
Yann 0:03314ad622d6 101
Yann 1:cf3cee91eb87 102 // Sanity check
Yann 1:cf3cee91eb87 103 if ((p_command != WriteToPot1) && (p_command != WriteToPot2) && (p_command != WriteToBoth)) {
Yann 1:cf3cee91eb87 104 // Wrong parameters
Yann 1:cf3cee91eb87 105 return (unsigned short) -1;
Yann 1:cf3cee91eb87 106 }
Yann 1:cf3cee91eb87 107
Yann 0:03314ad622d6 108 unsigned short command = 0;
Yann 0:03314ad622d6 109 switch (p_command) {
Yann 0:03314ad622d6 110 case WriteToPot1:
Yann 0:03314ad622d6 111 command = (0x11 << 8 | p_value);
Yann 0:03314ad622d6 112 break;
Yann 0:03314ad622d6 113 case WriteToPot2:
Yann 0:03314ad622d6 114 command = (0x12 << 8 | p_value);
Yann 0:03314ad622d6 115 break;
Yann 1:cf3cee91eb87 116 default:
Yann 0:03314ad622d6 117 command = (0x13 << 8 | p_value);
Yann 1:cf3cee91eb87 118 } // End of 'switch' statement
Yann 1:cf3cee91eb87 119
Yann 1:cf3cee91eb87 120 DEBUG("CMCP4xxxx_SPI: Send command: 0x%04x", command)
Yann 2:7c27fb9785be 121 if (_cs != NULL) {
Yann 2:7c27fb9785be 122 _cs->write(0);
Yann 2:7c27fb9785be 123 }
Yann 1:cf3cee91eb87 124 unsigned short result = _spiInstance->write(command);
Yann 2:7c27fb9785be 125 if (_cs != NULL) {
Yann 2:7c27fb9785be 126 _cs->write(1);
Yann 2:7c27fb9785be 127 }
Yann 1:cf3cee91eb87 128
Yann 1:cf3cee91eb87 129 DEBUG_LEAVE("CMCP4xxxx_SPI::Write: %d", result)
Yann 1:cf3cee91eb87 130 return result;
Yann 1:cf3cee91eb87 131 }
Yann 1:cf3cee91eb87 132
Yann 1:cf3cee91eb87 133 unsigned short CMCP4xxxx_SPI::Write(const Commands p_command) {
Yann 1:cf3cee91eb87 134 DEBUG_ENTER("CMCP4xxxx_SPI::Write: 0x%02x", (unsigned char)p_command)
Yann 1:cf3cee91eb87 135
Yann 1:cf3cee91eb87 136 // Sanity check
Yann 1:cf3cee91eb87 137 if ((p_command != ShutdownPot1) && (p_command != ShutdownPot2) && (p_command != ShutdownBoth)) {
Yann 1:cf3cee91eb87 138 // Wrong parameters
Yann 1:cf3cee91eb87 139 return (unsigned short) -1;
Yann 1:cf3cee91eb87 140 }
Yann 1:cf3cee91eb87 141
Yann 1:cf3cee91eb87 142 unsigned short command = 0;
Yann 1:cf3cee91eb87 143 switch (p_command) {
Yann 0:03314ad622d6 144 case ShutdownPot1:
Yann 0:03314ad622d6 145 command = (0x21 << 8);
Yann 0:03314ad622d6 146 break;
Yann 0:03314ad622d6 147 case ShutdownPot2:
Yann 0:03314ad622d6 148 command = (0x21 << 8);
Yann 0:03314ad622d6 149 break;
Yann 0:03314ad622d6 150 default: //<! Shutdown both digital potentiometers
Yann 0:03314ad622d6 151 command = (0x23 << 8);
Yann 0:03314ad622d6 152 } // End of 'switch' statement
Yann 0:03314ad622d6 153
Yann 0:03314ad622d6 154 DEBUG("CMCP4xxxx_SPI: Send command: 0x%04x", command)
Yann 2:7c27fb9785be 155 if (_cs != NULL) {
Yann 2:7c27fb9785be 156 _cs->write(0);
Yann 2:7c27fb9785be 157 }
Yann 0:03314ad622d6 158 unsigned short result = _spiInstance->write(command);
Yann 2:7c27fb9785be 159 if (_cs != NULL) {
Yann 2:7c27fb9785be 160 _cs->write(1);
Yann 2:7c27fb9785be 161 }
Yann 0:03314ad622d6 162
Yann 0:03314ad622d6 163 DEBUG_LEAVE("CMCP4xxxx_SPI::Write: %d", result)
Yann 0:03314ad622d6 164 return result;
Yann 0:03314ad622d6 165 }
Yann 0:03314ad622d6 166 unsigned short CMCP4xxxx_SPI::Write() {
Yann 0:03314ad622d6 167 return _spiInstance->write(0);
Yann 0:03314ad622d6 168 }
Yann 0:03314ad622d6 169
Yann 0:03314ad622d6 170 bool CMCP4xxxx_SPI::Reset() {
Yann 0:03314ad622d6 171 // Sanity check
Yann 0:03314ad622d6 172 if (_reset == NULL) {
Yann 0:03314ad622d6 173 return false;
Yann 0:03314ad622d6 174 }
Yann 0:03314ad622d6 175
Yann 0:03314ad622d6 176 _reset->write(0); // Set level low to activate reset
Yann 0:03314ad622d6 177 wait_us(1); // Wait for 1us
Yann 2:7c27fb9785be 178 _reset->write(1); // Set level low to de-activate reset
Yann 0:03314ad622d6 179
Yann 0:03314ad622d6 180 return true;
Yann 0:03314ad622d6 181 }
Yann 0:03314ad622d6 182
Yann 0:03314ad622d6 183 bool CMCP4xxxx_SPI::Shutdown(const bool p_set) {
Yann 0:03314ad622d6 184 // Sanity check
Yann 0:03314ad622d6 185 if (_shdn == NULL) {
Yann 0:03314ad622d6 186 return false;
Yann 0:03314ad622d6 187 }
Yann 0:03314ad622d6 188
Yann 0:03314ad622d6 189 _shdn->write(p_set == false ? 0 : 1);
Yann 0:03314ad622d6 190
Yann 0:03314ad622d6 191 return true;
Yann 0:03314ad622d6 192 }
Yann 0:03314ad622d6 193
Yann 0:03314ad622d6 194 } // End of namespace MCP4xxxx_SPI