This library provides simplified I2C access to a Microchip MCP23x17 GPIO expender device, including a general interface for any GPIO expender

Dependents:   MCP23017App

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MCP23017_I2C.h Source File

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;