Simplified access to a Microchip Digital Potentiometer (MCP41xxx/MCP42xxx) devices
Dependents: MCP41xxxApp MCP320xApp MCP41xxxApp
MCP4xxxx_SPI.cpp@4:bbfc8e352ff5, 2013-02-04 (annotated)
- 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?
User | Revision | Line number | New 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 |