This library provides simplified I2C access to a Microchip MCP23x17 GPIO expender device, including a general interface for any GPIO expender
MCP23017_I2C.h
00001 /* mbed simplified access to Microchip MCP23x17 GPIO expender devices (I2C) 00002 * Copyright (c) 2014-2015 ygarcia, MIT License 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00005 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00006 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00007 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in all copies or 00011 * substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00014 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00015 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00016 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00017 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00018 */ 00019 #pragma once 00020 00021 #include <map> 00022 00023 #include "Debug.h" 00024 00025 #include "AbstractGpioExpender.h" 00026 00027 namespace MCP23017_I2C { 00028 /** This class provides simplified I2C access to a Microchip 2MCP28x17 GPIO expender. V0.0.0.1 00029 * 00030 * Note that if the LPC1768 is powered in 3.3V and Microchip MCP28x17 GPIO expender device could be powered at 3.3V or 5V. 00031 * In this case, you shall use a bi-directional level shifter for I2C-bus. Please refer to AN97055 (http://ics.nxp.com/support/documents/interface/pdf/an97055.pdf) 00032 * Microchip MCP28x17 GPIO expender device reference: DS21952B 00033 * 00034 * Note that for I2C details, please visit http://www.datelec.fr/fiches/I2C.htm 00035 * 00036 * Note that this header file include following headers: 00037 * - <string> 00038 * - <vector> 00039 * - <mbed.h> 00040 * 00041 * @author Yann Garcia (Don't hesitate to contact me: garcia.yann@gmail.com) 00042 */ 00043 class CMCP23017_I2C : public AbstractGpioExpender { 00044 00045 /** Reference counter used to guarentee unicity of the instance of I2C class 00046 */ 00047 static unsigned char I2CModuleRefCounter; 00048 00049 /** Device address input: A0, A1, A2 (Pins <1,3>). See DS21203K/DS21189D - Figure 5-1: Control Byte Format for address format details 00050 */ 00051 unsigned char _slaveAddress; 00052 00053 /** Interrupt on GPIOA 00054 */ 00055 InterruptIn *_intA; 00056 00057 /** Interrupt on GPIOB 00058 */ 00059 InterruptIn *_intB; 00060 00061 /** Device reset pin 00062 */ 00063 DigitalOut *_reset; 00064 00065 /** PortA config 00066 */ 00067 unsigned char _gpioAFlags; 00068 00069 /** PortB config 00070 */ 00071 unsigned char _gpioBFlags; 00072 00073 /** Map of declared buses 00074 */ 00075 std::map<unsigned char, std::list<unsigned char> > _buses; 00076 00077 /** Buses identifier index 00078 */ 00079 unsigned char _busesIndex; 00080 00081 /** An unique instance of I2C class 00082 */ 00083 I2C *_i2cInstance; 00084 00085 public: 00086 /** Constructor with Write Protect command pin wired. Use it to manage the first I2C module on 3.3V or 5V network 00087 * 00088 * @param p_sda: MBed pin for SDA 00089 * @param p_scl: MBed pin for SCL 00090 * @param p_address: Device address input: A0, A1, A2 (Pins <1,3>) 00091 * @param p_intA: MBed pin to manage interrupt on GPIOA, default value is NC, not connected 00092 * @param p_intB: MBed pin to manage device reset. If NC, WP is not managed, default value is NC, not connected 00093 * @param p_reset: MBed pin to manage Write Protect input. If NC, WP is not managed, default value is NC, not connected 00094 * @param p_internalPullUp: Set to true to use internal pull-up resistor, default value is true 00095 * @param p_frequency: Frequency of the I2C interface (SCL), default value is 400KHz 00096 * Example: 00097 * - If A1 and A2 pins are tired to Vdd and A0 is tired to Vss, address shall '00000110'B 00098 * - If A0 and A1 pins are tired to Vss and A2 is tired to Vdd, address shall '00000100'B 00099 */ 00100 CMCP23017_I2C(const PinName p_sda, const PinName p_scl, const unsigned char p_address, const PinName p_intA = NC, const PinName p_intB = NC, const PinName p_reset = NC, const bool p_internalPullUp = true, const unsigned int p_frequency = 400000); 00101 00102 /** Destructor 00103 */ 00104 virtual ~CMCP23017_I2C(); 00105 00106 /** Initialize the module, configuring the module and starting the clock 00107 * @param p_gpioAFlags GPIO A port configuration: bit set for input mode, 0 for output mode. Default: ports as outputs 00108 * @param p_gpioBFlags GPIO B port configuration: bit set for input mode, 0 for output mode. Default: ports as outputs 00109 * 00110 * @return true on success, false otherwise 00111 */ 00112 bool Initialize(const unsigned char p_gpioAFlags = 0x00, const unsigned char p_gpioBFlags = 0x00); 00113 00114 /** Used to return the unique instance of I2C instance 00115 */ 00116 inline const I2C * operator * () { return (const I2C *)_i2cInstance; }; 00117 00118 /** Reset the device 00119 */ 00120 virtual void reset(); 00121 00122 /** Setup device interrupt mechanism 00123 * @param p_mirroring Set to 0x00 to disable INTA/B mirroring, 0x01 otherwise. Default: 0x00 00124 * @param p_openDrain Set to 0x00 for active driver output, 0x01 for opn drain output. Default: 0x00 00125 * @param p_polarity Set to 0x00 for interrupt active low, 0x01 otherwise. Default: 0x00 00126 */ 00127 virtual void setupInterrupts(const unsigned char mirroring = 0x00, const unsigned char p_openDrain = 0x00, const unsigned char polarity = 0x00); 00128 00129 /** Setup interrupt for a specific IO port 00130 * @param p_pinId The IO port identifier 00131 * @param p_mode The interrupt mode 00132 * @return 0 on success, -1 on wrong parameters and -2 otherwise 00133 */ 00134 virtual int setupInterruptPin(const unsigned char p_gpioId, const InterruptModes p_mode = OnRising); 00135 00136 /** Setup pull mode for a specific IO port 00137 * @param p_gpioId The IO port identifier 00138 * @param p_mode The interrupt mode 00139 * @return 0 on success, -1 on wrong parameters and -2 otherwise 00140 */ 00141 virtual int setupPullPin(const unsigned char p_gpioId, const PullModes p_mode = PullOff); 00142 00143 /** Get interrupt information and clear it 00144 * @param p_gpioId The IO port identifier where the interrupt occured 00145 * @param p_value The logic value on the pin port where the interrupt occured 00146 * @return 0 on success, -1 on wrong parameters and -2 otherwise 00147 */ 00148 virtual int getLastInterruptPinAndValue(unsigned char * p_gpioId, unsigned char * p_value); 00149 00150 /** Read the specific GPIO port pin 00151 * @param p_gpioId The GPIO port pin to be read 00152 * @param p_value The GPIO port pin value 00153 * @return 0 on success, -1 on wrong parameters and -2 otherwise 00154 */ 00155 virtual int read(const unsigned char p_gpioId, unsigned char * p_value); 00156 00157 /** Write value to the specific GPIO port pin 00158 * @param p_gpioId The GPIO port pin to be written 00159 * @param p_value The GPIO port pin value 00160 * @return 0 on success, -1 on wrong parameters and -2 otherwise 00161 */ 00162 virtual int write(const unsigned char p_gpioId, const unsigned char p_value); 00163 00164 virtual unsigned char createBus(const std::list<unsigned char> p_lines, const PinMode p_mode = PullNone); 00165 virtual void deleteBus(const unsigned char p_busId); 00166 virtual int busRead(const unsigned char p_busId, unsigned short * p_value); 00167 virtual int busWrite(const unsigned char p_busId, const unsigned short p_value); 00168 00169 /** Attach a function to call when a interrupt occurs on the GPIOA input ports 00170 * @param p_fptr The pointer to the "C" callback function 00171 */ 00172 virtual void setIntrACallback(void (* p_fptr)(void)); 00173 00174 /** Attach a function to call when a interrupt occurs on the GPIOB input ports 00175 * @param p_fptr The pointer to the "C" callback function 00176 */ 00177 virtual void setIntrBCallback(void (* p_fptr)(void)); 00178 00179 /** Attach a member function to call when a interrupt occurs on the GPIOA input ports 00180 */ 00181 template<typename T> 00182 void setIntrACallback(const T * p_tptr, void(T::* p_mptr)(void)); 00183 00184 /** Attach a member function to call when a rising edge occurs on the input 00185 */ 00186 template<typename T> 00187 void setIntrBCallback(const T * p_tptr, void(T::* p_mptr)(void)); 00188 00189 private: 00190 00191 /** Configure the device: 00192 * BANK0 (A register followed by B register) 00193 * INTs: active low 00194 * INTs for all ports 00195 * INTs are not mirrored 00196 * @param p_gpioAFlags GPIO A port configuration: bit set for input mode, 0 for output mode. Default: ports as outputs 00197 * @param p_gpioBFlags GPIO B port configuration: bit set for input mode, 0 for output mode. Default: ports as outputs 00198 */ 00199 void configure(const unsigned char p_gpioAFlags, const unsigned char p_gpioBFlags); 00200 00201 bool registerIdFromGpioId(const unsigned char p_gpioId, unsigned char * p_gpioRegisterId); 00202 00203 inline unsigned char gpioBitFromGpioId(const unsigned char p_gpioId) { 00204 return static_cast<unsigned char>((p_gpioId < GPIO_MED) ? p_gpioId : (p_gpioId - GPIO_MED)); 00205 }; 00206 inline bool isBitSet(const unsigned char p_gpioRegisterValue, const unsigned char p_gpioBit) { 00207 return (bool)((unsigned char)(p_gpioRegisterValue >> p_gpioBit) == 0x01); 00208 }; 00209 inline bool isBitEqual(const unsigned char p_gpioRegisterValue, const unsigned char p_gpioBit, const unsigned char p_value) { 00210 return (bool)((unsigned char)(p_gpioRegisterValue >> p_gpioBit) == (p_value & 0x01)); 00211 }; 00212 inline unsigned char setBit(unsigned char p_gpioRegisterValue, const unsigned char p_gpioBit, const unsigned char p_value) { 00213 return (p_gpioRegisterValue & ~(1 << p_gpioBit)) | ((p_value & 0x01) << p_gpioBit); 00214 }; 00215 00216 protected: 00217 00218 /** Write value to a register 00219 * @param p_address The register address 00220 * @param p_byte The value to write to the register 00221 * @return 1 on success, false otherwise 00222 */ 00223 virtual bool writeRegister(const unsigned char p_registerId, const unsigned char p_value); 00224 00225 virtual bool readRegister(const unsigned char p_registerId, unsigned char * p_value); 00226 00227 private: 00228 /** Internal reference identifier 00229 */ 00230 std::string _internalId; 00231 00232 void DumpRegisters(); 00233 void DumpRegister(unsigned int p_registerId); 00234 00235 }; // End of class CMCP23017_I2C 00236 00237 } // End of namespace _MCP23017_I2C 00238 00239 using namespace MCP23017_I2C;
Generated on Tue Jul 12 2022 15:16:48 by 1.7.2