Simplified access to a Microchip Digital Potentiometer (MCP41xxx/MCP42xxx) devices
Dependents: MCP41xxxApp MCP320xApp MCP41xxxApp
MCP4xxxx_SPI.cpp@2:7c27fb9785be, 2013-01-29 (annotated)
- Committer:
- Yann
- Date:
- Tue Jan 29 15:02:08 2013 +0000
- Revision:
- 2:7c27fb9785be
- Parent:
- 1:cf3cee91eb87
- Child:
- 4:bbfc8e352ff5
Add /CS supported by library
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Yann | 0:03314ad622d6 | 1 | /* mbed simplified access to Microchip 24LCxx Serial EEPROM 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 | 0:03314ad622d6 | 29 | if (CMCP4xxxx_SPI::SPIModuleRefCounter != 0) { |
Yann | 0:03314ad622d6 | 30 | error("CMCP4xxxx_SPI: Wrong params"); |
Yann | 0:03314ad622d6 | 31 | } |
Yann | 0:03314ad622d6 | 32 | |
Yann | 0:03314ad622d6 | 33 | _spiInstance = new SPI(p_mosi, p_miso, p_sclk); |
Yann | 0:03314ad622d6 | 34 | _spiInstance->frequency(p_frequency); // Set the frequency of the SPI interface |
Yann | 0:03314ad622d6 | 35 | _spiInstance->format(16, 0); // See http://mbed.org/users/mbed_official/code/mbed/docs/0954ebd79f59//classmbed_1_1SPI.html |
Yann | 0:03314ad622d6 | 36 | CMCP4xxxx_SPI::SPIModuleRefCounter += 1; |
Yann | 0:03314ad622d6 | 37 | DEBUG_ENTER("CMCP4xxxx_SPI: refCounter=%d", CMCP4xxxx_SPI::SPIModuleRefCounter) |
Yann | 0:03314ad622d6 | 38 | |
Yann | 2:7c27fb9785be | 39 | if (p_cs != NC) { |
Yann | 2:7c27fb9785be | 40 | DEBUG("CMCP4xxxx_SPI: /CS managed"); |
Yann | 2:7c27fb9785be | 41 | _cs = new DigitalOut(p_cs); |
Yann | 2:7c27fb9785be | 42 | _cs->write(1); // Disable chip |
Yann | 2:7c27fb9785be | 43 | } else { |
Yann | 2:7c27fb9785be | 44 | DEBUG("CMCP4xxxx_SPI: /CS not managed"); |
Yann | 2:7c27fb9785be | 45 | _cs = NULL; // Not used |
Yann | 2:7c27fb9785be | 46 | } |
Yann | 2:7c27fb9785be | 47 | |
Yann | 0:03314ad622d6 | 48 | if (p_reset != NC) { |
Yann | 0:03314ad622d6 | 49 | DEBUG("CMCP4xxxx_SPI: /RESET managed"); |
Yann | 0:03314ad622d6 | 50 | _reset = new DigitalOut(p_reset); |
Yann | 0:03314ad622d6 | 51 | _reset->write(1); // Disable reset |
Yann | 0:03314ad622d6 | 52 | } else { |
Yann | 0:03314ad622d6 | 53 | DEBUG("CMCP4xxxx_SPI: /RESET not managed"); |
Yann | 0:03314ad622d6 | 54 | _reset = NULL; // Not used |
Yann | 0:03314ad622d6 | 55 | } |
Yann | 0:03314ad622d6 | 56 | |
Yann | 0:03314ad622d6 | 57 | if (p_shdn != NC) { |
Yann | 0:03314ad622d6 | 58 | DEBUG("CMCP4xxxx_SPI: /SHDN managed"); |
Yann | 0:03314ad622d6 | 59 | _shdn = new DigitalOut(p_shdn); |
Yann | 0:03314ad622d6 | 60 | _shdn->write(1); // Disable shutdown |
Yann | 0:03314ad622d6 | 61 | } else { |
Yann | 0:03314ad622d6 | 62 | DEBUG("CMCP4xxxx_SPI: /SHDN not managed"); |
Yann | 0:03314ad622d6 | 63 | _shdn = NULL; // Not used |
Yann | 0:03314ad622d6 | 64 | } |
Yann | 0:03314ad622d6 | 65 | |
Yann | 0:03314ad622d6 | 66 | DEBUG_LEAVE("CMCP4xxxx_SPI") |
Yann | 0:03314ad622d6 | 67 | } |
Yann | 0:03314ad622d6 | 68 | |
Yann | 0:03314ad622d6 | 69 | CMCP4xxxx_SPI::~CMCP4xxxx_SPI() { |
Yann | 0:03314ad622d6 | 70 | DEBUG_ENTER("~CMCP4xxxx_SPI") |
Yann | 0:03314ad622d6 | 71 | |
Yann | 0:03314ad622d6 | 72 | // Release I2C instance |
Yann | 0:03314ad622d6 | 73 | DEBUG_ENTER("~CMCP4xxxx_SPI: refCounter=%d", CMCP4xxxx_SPI::SPIModuleRefCounter) |
Yann | 0:03314ad622d6 | 74 | CMCP4xxxx_SPI::SPIModuleRefCounter -= 1; |
Yann | 0:03314ad622d6 | 75 | if (CMCP4xxxx_SPI::SPIModuleRefCounter == 0) { |
Yann | 0:03314ad622d6 | 76 | delete _spiInstance; |
Yann | 0:03314ad622d6 | 77 | _spiInstance = NULL; |
Yann | 0:03314ad622d6 | 78 | } |
Yann | 0:03314ad622d6 | 79 | // Release _reset if required |
Yann | 2:7c27fb9785be | 80 | if (_cs != NULL) { |
Yann | 2:7c27fb9785be | 81 | _cs->write(0); |
Yann | 2:7c27fb9785be | 82 | delete _cs; |
Yann | 2:7c27fb9785be | 83 | } |
Yann | 2:7c27fb9785be | 84 | // Release _reset if required |
Yann | 0:03314ad622d6 | 85 | if (_reset != NULL) { |
Yann | 0:03314ad622d6 | 86 | _reset->write(0); |
Yann | 0:03314ad622d6 | 87 | delete _reset; |
Yann | 0:03314ad622d6 | 88 | } |
Yann | 2:7c27fb9785be | 89 | // Release _shdn if required |
Yann | 0:03314ad622d6 | 90 | if (_shdn != NULL) { |
Yann | 0:03314ad622d6 | 91 | _shdn->write(0); |
Yann | 0:03314ad622d6 | 92 | delete _shdn; |
Yann | 0:03314ad622d6 | 93 | } |
Yann | 0:03314ad622d6 | 94 | |
Yann | 0:03314ad622d6 | 95 | DEBUG_LEAVE("~CMCP4xxxx_SPI") |
Yann | 0:03314ad622d6 | 96 | } |
Yann | 0:03314ad622d6 | 97 | |
Yann | 0:03314ad622d6 | 98 | unsigned short CMCP4xxxx_SPI::Write(const Commands p_command, const unsigned char p_value) { |
Yann | 0:03314ad622d6 | 99 | DEBUG_ENTER("CMCP4xxxx_SPI::Write: 0x%02x - 0x%02x", (unsigned char)p_command, p_value) |
Yann | 0:03314ad622d6 | 100 | |
Yann | 1:cf3cee91eb87 | 101 | // Sanity check |
Yann | 1:cf3cee91eb87 | 102 | if ((p_command != WriteToPot1) && (p_command != WriteToPot2) && (p_command != WriteToBoth)) { |
Yann | 1:cf3cee91eb87 | 103 | // Wrong parameters |
Yann | 1:cf3cee91eb87 | 104 | return (unsigned short) -1; |
Yann | 1:cf3cee91eb87 | 105 | } |
Yann | 1:cf3cee91eb87 | 106 | |
Yann | 0:03314ad622d6 | 107 | unsigned short command = 0; |
Yann | 0:03314ad622d6 | 108 | switch (p_command) { |
Yann | 0:03314ad622d6 | 109 | case WriteToPot1: |
Yann | 0:03314ad622d6 | 110 | command = (0x11 << 8 | p_value); |
Yann | 0:03314ad622d6 | 111 | break; |
Yann | 0:03314ad622d6 | 112 | case WriteToPot2: |
Yann | 0:03314ad622d6 | 113 | command = (0x12 << 8 | p_value); |
Yann | 0:03314ad622d6 | 114 | break; |
Yann | 1:cf3cee91eb87 | 115 | default: |
Yann | 0:03314ad622d6 | 116 | command = (0x13 << 8 | p_value); |
Yann | 1:cf3cee91eb87 | 117 | } // End of 'switch' statement |
Yann | 1:cf3cee91eb87 | 118 | |
Yann | 1:cf3cee91eb87 | 119 | DEBUG("CMCP4xxxx_SPI: Send command: 0x%04x", command) |
Yann | 2:7c27fb9785be | 120 | if (_cs != NULL) { |
Yann | 2:7c27fb9785be | 121 | _cs->write(0); |
Yann | 2:7c27fb9785be | 122 | } |
Yann | 1:cf3cee91eb87 | 123 | unsigned short result = _spiInstance->write(command); |
Yann | 2:7c27fb9785be | 124 | if (_cs != NULL) { |
Yann | 2:7c27fb9785be | 125 | _cs->write(1); |
Yann | 2:7c27fb9785be | 126 | } |
Yann | 1:cf3cee91eb87 | 127 | |
Yann | 1:cf3cee91eb87 | 128 | DEBUG_LEAVE("CMCP4xxxx_SPI::Write: %d", result) |
Yann | 1:cf3cee91eb87 | 129 | return result; |
Yann | 1:cf3cee91eb87 | 130 | } |
Yann | 1:cf3cee91eb87 | 131 | |
Yann | 1:cf3cee91eb87 | 132 | unsigned short CMCP4xxxx_SPI::Write(const Commands p_command) { |
Yann | 1:cf3cee91eb87 | 133 | DEBUG_ENTER("CMCP4xxxx_SPI::Write: 0x%02x", (unsigned char)p_command) |
Yann | 1:cf3cee91eb87 | 134 | |
Yann | 1:cf3cee91eb87 | 135 | // Sanity check |
Yann | 1:cf3cee91eb87 | 136 | if ((p_command != ShutdownPot1) && (p_command != ShutdownPot2) && (p_command != ShutdownBoth)) { |
Yann | 1:cf3cee91eb87 | 137 | // Wrong parameters |
Yann | 1:cf3cee91eb87 | 138 | return (unsigned short) -1; |
Yann | 1:cf3cee91eb87 | 139 | } |
Yann | 1:cf3cee91eb87 | 140 | |
Yann | 1:cf3cee91eb87 | 141 | unsigned short command = 0; |
Yann | 1:cf3cee91eb87 | 142 | switch (p_command) { |
Yann | 0:03314ad622d6 | 143 | case ShutdownPot1: |
Yann | 0:03314ad622d6 | 144 | command = (0x21 << 8); |
Yann | 0:03314ad622d6 | 145 | break; |
Yann | 0:03314ad622d6 | 146 | case ShutdownPot2: |
Yann | 0:03314ad622d6 | 147 | command = (0x21 << 8); |
Yann | 0:03314ad622d6 | 148 | break; |
Yann | 0:03314ad622d6 | 149 | default: //<! Shutdown both digital potentiometers |
Yann | 0:03314ad622d6 | 150 | command = (0x23 << 8); |
Yann | 0:03314ad622d6 | 151 | } // End of 'switch' statement |
Yann | 0:03314ad622d6 | 152 | |
Yann | 0:03314ad622d6 | 153 | DEBUG("CMCP4xxxx_SPI: Send command: 0x%04x", command) |
Yann | 2:7c27fb9785be | 154 | if (_cs != NULL) { |
Yann | 2:7c27fb9785be | 155 | _cs->write(0); |
Yann | 2:7c27fb9785be | 156 | } |
Yann | 0:03314ad622d6 | 157 | unsigned short result = _spiInstance->write(command); |
Yann | 2:7c27fb9785be | 158 | if (_cs != NULL) { |
Yann | 2:7c27fb9785be | 159 | _cs->write(1); |
Yann | 2:7c27fb9785be | 160 | } |
Yann | 0:03314ad622d6 | 161 | |
Yann | 0:03314ad622d6 | 162 | DEBUG_LEAVE("CMCP4xxxx_SPI::Write: %d", result) |
Yann | 0:03314ad622d6 | 163 | return result; |
Yann | 0:03314ad622d6 | 164 | } |
Yann | 0:03314ad622d6 | 165 | unsigned short CMCP4xxxx_SPI::Write() { |
Yann | 0:03314ad622d6 | 166 | return _spiInstance->write(0); |
Yann | 0:03314ad622d6 | 167 | } |
Yann | 0:03314ad622d6 | 168 | |
Yann | 0:03314ad622d6 | 169 | bool CMCP4xxxx_SPI::Reset() { |
Yann | 0:03314ad622d6 | 170 | // Sanity check |
Yann | 0:03314ad622d6 | 171 | if (_reset == NULL) { |
Yann | 0:03314ad622d6 | 172 | return false; |
Yann | 0:03314ad622d6 | 173 | } |
Yann | 0:03314ad622d6 | 174 | |
Yann | 0:03314ad622d6 | 175 | _reset->write(0); // Set level low to activate reset |
Yann | 0:03314ad622d6 | 176 | wait_us(1); // Wait for 1us |
Yann | 2:7c27fb9785be | 177 | _reset->write(1); // Set level low to de-activate reset |
Yann | 0:03314ad622d6 | 178 | |
Yann | 0:03314ad622d6 | 179 | return true; |
Yann | 0:03314ad622d6 | 180 | } |
Yann | 0:03314ad622d6 | 181 | |
Yann | 0:03314ad622d6 | 182 | bool CMCP4xxxx_SPI::Shutdown(const bool p_set) { |
Yann | 0:03314ad622d6 | 183 | // Sanity check |
Yann | 0:03314ad622d6 | 184 | if (_shdn == NULL) { |
Yann | 0:03314ad622d6 | 185 | return false; |
Yann | 0:03314ad622d6 | 186 | } |
Yann | 0:03314ad622d6 | 187 | |
Yann | 0:03314ad622d6 | 188 | _shdn->write(p_set == false ? 0 : 1); |
Yann | 0:03314ad622d6 | 189 | |
Yann | 0:03314ad622d6 | 190 | return true; |
Yann | 0:03314ad622d6 | 191 | } |
Yann | 0:03314ad622d6 | 192 | |
Yann | 0:03314ad622d6 | 193 | } // End of namespace MCP4xxxx_SPI |