The PCAL6416A is a low-voltage 16-bit general purpose I/O (GPIO) expander with interrupt. This component library is compatible to basic operation as GPIO expanders: PCAL6416A, PCAL9555, PCA9555, PCA9535, PCA9539, PCAL9554, PCA9554 and PCA9538. On addition to this, this library is including mbed-SDK-style APIs. APIs that similar to DigitaiInOut, DigitalOut, DigitalIn, BusInOUt, BusOut and BusIn are available.

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers PCAL6416.h Source File

PCAL6416.h

00001 /** PCAL6416A 16-bit I2C-bus GPIO expander
00002  *
00003  *  An operation sample of PCA(L)9555, PCA9535, PCA9539 and PCAL6416.
00004  *  mbed accesses the PCAL6416 registers through I2C.
00005  *
00006  *  @class    PCAL6416
00007  *  @author   Akifumi (Tedd) OKANO, NXP Semiconductors
00008  *  @version  0.6.1
00009  *  @date     19-Mar-2015
00010  *  @modified 15-Feb-2017, by Andriy Makukha, Shenzhen MZJ Technology Co.
00011  *
00012  *  Released under the Apache 2 license
00013  *
00014  *  About PCAL6416:
00015  *    http://www.nxp.com/documents/data_sheet/PCAL6416A.pdf
00016  */
00017 
00018 #ifndef     MBED_PCAL6416
00019 #define     MBED_PCAL6416
00020 
00021 #include    "mbed.h"
00022 #include    "PCAL955x.h"
00023 #include    "CompGpioExpAPI.h"
00024 
00025 /** PCAL6416 class
00026  *
00027  *  This is a driver code for the Low-voltage 16-bit I2C-bus GPIO with Agile I/O.
00028  *  This class provides interface for PCAL6416 operation.
00029  *  Detail information is available on next URL.
00030  *    http://www.nxp.com/documents/data_sheet/PCAL6416A.pdf
00031  *  
00032  *  PCAL9555 library's basic IO operation is compatible to PCA9555, PCA9535, PCAL6416A and PCA9539.
00033  *  This library can be used for those GPIO expander chips also.
00034  *  Next sample code shows operation based on low-level-API (operated by just device instane)
00035  *  
00036  *  Example:
00037  *  @code
00038  *  //  GPIO-expander operation sample using a device instance
00039  *  
00040  *  #include    "mbed.h"
00041  *  #include    "PCAL6416.h"
00042  *
00043  *  PCAL6416    gpio( p28, p27, 0xE8 );     //  using PCA9539
00044  *
00045  *  int main() {
00046  *      gpio.configure( 0xFFFF );           //  Set all pins: input
00047  *      printf( "  0x%04X\r\n", (int)gpio );//  Print pins state
00048  *
00049  *      gpio.configure( 0x0000 );           //  Set all pins: output
00050  *      int count   = 0;
00051  *      while(1) {
00052  *          gpio.write( count++ );
00053  *      }
00054  *  }
00055  *  @endcode
00056  *
00057  *  GpioDigitalInOut, GpioDigitalOut, GpioDigitalIn,
00058  *  GpioBusInOut, GpioBusOut and GpioBusIn API class are available also.
00059  *  For those high-level-API details, please find those class library page.
00060  *  The GpioDigital* and GpioBus* APIs can be used like next sample code.
00061  *
00062  *  @code
00063  *  //  GPIO-expander operation sample using high-level-API
00064  *  
00065  *  #include    "mbed.h"
00066  *  #include    "PCAL6416.h"
00067  *
00068  *  PCAL6416        gpio( p28, p27, 0xE8 );     //  using PCA9539
00069  *
00070  *  //  The GPIO pins are grouped in some groups and operated as bus I/O
00071  *  GpioBusIn       bus_in( gpio, X0_0, X0_1, X0_2, X0_3 );
00072  *  GpioBusOut      bus_out( gpio, X0_4, X0_5, X0_6 );
00073  *  GpioBusInOut    bus_io( gpio, X1_7, X1_6, X1_5, X1_4, X1_3, X1_2, X1_1, X1_0 );
00074  *  GpioDigitalOut  myled( gpio, X0_7 );
00075  *
00076  *  int main() {
00077  *      bus_io.input();
00078  *      printf( "I/O = 0x%02X\r\n", (int)bus_io );
00079  *      printf( "In  = 0x%01X\r\n", (int)bus_in );
00080  *
00081  *      bus_io.output();
00082  *
00083  *      int count   = 0;
00084  *      while(1) {
00085  *          bus_out = count;
00086  *          bus_io  = count;
00087  *          myled   = count & 0x1;
00088  *          count++;
00089  *          wait( 0.1 );
00090  *      }
00091  *  }
00092  *  @endcode
00093  */
00094 
00095 class PCAL6416 : public PCAL955x
00096 {
00097 public:
00098     /** Name of the PCAL6416 registers */
00099     enum command_reg {
00100         InputPort0              = 0x00, /**< InputPort0 register                */
00101         InputPort1,                     /**< InputPort1 register                */
00102         OutoutPort0,                    /**< OutoutPort0 register               */
00103         OutoutPort1,                    /**< OutoutPort1 register               */
00104         PolarityInversionPort0,         /**< PolarityInversionPort0 register    */
00105         PolarityInversionPort1,         /**< PolarityInversionPort1 register    */
00106         ConfigurationPort0,             /**< ConfigurationPort0 register        */
00107         ConfigurationPort1,             /**< ConfigurationPort1 register        */
00108         OutputDriveStrength0_0  = 0x40, /**< OutputDriveStrength0_0 register    */
00109         OutputDriveStrength0_1,         /**< OutputDriveStrength0_1 register    */
00110         OutputDriveStrength1_0,         /**< OutputDriveStrength1_0 register    */
00111         OutputDriveStrength1_1,         /**< OutputDriveStrength1_1 register    */
00112         InputLatch0,                    /**< InputLatch0 register               */
00113         InputLatch1,                    /**< InputLatch1 register               */
00114         PullUpPullDowmEnable0,          /**< PullUpPullDowmEnable0 register     */
00115         PullUpPullDowmEnable1,          /**< PullUpPullDowmEnable1 register     */
00116         PullUpPullDowmSelection0,       /**< PullUpPullDowmSelection0 register  */
00117         PullUpPullDowmSelection1,       /**< PullUpPullDowmSelection1 register  */
00118         InterruptMask0,                 /**< InterruptMask0 register            */
00119         InterruptMask1,                 /**< InterruptMask1 register            */
00120         InterruptStatus0,               /**< InterruptStatus0 register          */
00121         InterruptStatus1,               /**< InterruptStatus1 register          */
00122         OutputPortConfiguration = 0x4F, /**< OutputPortConfiguration register   */
00123     };
00124 
00125 #if DOXYGEN_ONLY
00126     /** GPIO-Expander pin names
00127      *    for when the high-level APIs 
00128      *    (GpioDigitalOut, GpioDigitalInOut, GpioDigitalIn, 
00129      *    GpioBusOut, GpioBusInOut are GpioBusIn) are used
00130      */
00131     typedef enum {
00132         X0_0,           /**< P0_0 pin */
00133         X0_1,           /**< P0_1 pin */
00134         X0_2,           /**< P0_2 pin */
00135         X0_3,           /**< P0_3 pin */
00136         X0_4,           /**< P0_4 pin */
00137         X0_5,           /**< P0_5 pin */
00138         X0_6,           /**< P0_6 pin */
00139         X0_7,           /**< P0_7 pin */
00140         X1_0,           /**< P1_0 pin */
00141         X1_1,           /**< P1_1 pin */
00142         X1_2,           /**< P1_2 pin */
00143         X1_3,           /**< P1_3 pin */
00144         X1_4,           /**< P1_4 pin */
00145         X1_5,           /**< P1_5 pin */
00146         X1_6,           /**< P1_6 pin */
00147         X1_7,           /**< P1_7 pin */
00148         X0  = X0_0,     /**< P0_0 pin */
00149         X1  = X0_1,     /**< P0_1 pin */
00150         X2  = X0_2,     /**< P0_2 pin */
00151         X3  = X0_3,     /**< P0_3 pin */
00152         X4  = X0_4,     /**< P0_4 pin */
00153         X5  = X0_5,     /**< P0_5 pin */
00154         X6  = X0_6,     /**< P0_6 pin */
00155         X7  = X0_7,     /**< P0_7 pin */
00156         X8  = X1_0,     /**< P1_0 pin */
00157         X9  = X1_1,     /**< P1_1 pin */
00158         X10 = X1_2,     /**< P1_2 pin */
00159         X11 = X1_3,     /**< P1_3 pin */
00160         X12 = X1_4,     /**< P1_4 pin */
00161         X13 = X1_5,     /**< P1_5 pin */
00162         X14 = X1_6,     /**< P1_6 pin */
00163         X15 = X1_7,     /**< P1_7 pin */
00164 
00165         X_NC = ~0x0L    /**< for when the pin is left no-connection */
00166     } GpioPinName;
00167 #endif
00168 
00169     /** Create a PCAL6416 instance connected to specified I2C pins with specified address
00170      *
00171      * @param i2c_sda       I2C-bus SDA pin
00172      * @param i2c_sda       I2C-bus SCL pin
00173      * @param i2c_address   I2C-bus address (default: 0x40)
00174      */
00175     PCAL6416( PinName i2c_sda, PinName i2c_scl, char i2c_address = PCAL955x::DEFAULT_I2C_ADDR );
00176 
00177     /** Create a PCAL6416 instance connected to specified I2C pins with specified address
00178      *
00179      * @param i2c_obj       I2C object (instance)
00180      * @param i2c_address   I2C-bus address (default: 0x40)
00181      */
00182     PCAL6416( I2C &i2c_obj, char i2c_address = PCAL955x::DEFAULT_I2C_ADDR );
00183 
00184     /** Destractor
00185      */
00186     virtual         ~PCAL6416();
00187 
00188     /** Returns the number of I/O pins
00189      *
00190      *  @returns
00191      *    The number of I/O pins
00192      */
00193     virtual int     number_of_pins( void );
00194 
00195 #if DOXYGEN_ONLY
00196 
00197     /** Set output port bits
00198      *
00199      *  @param bit_pattern  16-bit output pattern for port1 and port0.
00200      *
00201      *  @note
00202      *    The data for pins, given as integer.
00203      *    The 16-bit MSB goes to P1_7 pin and LSB goes to P0_0 pin.
00204      *    Data will not come out from the pin if it is configured as input.
00205      *
00206      *  @see configure()
00207      */
00208     void            write( int bit_pattern );
00209 
00210     /** Read pin states
00211      *
00212      *  @return
00213      *    16-bit pattern from port1 and port0.
00214      *
00215      *  @note
00216      *    The data from pins, given as integer.
00217      *    The 16-bit port data comes from IO pins, P1_7 as MSB, P0_0 as LSB.
00218      *    Data cannot be read if the port is configured as output.
00219      *
00220      *  @see configure()
00221      */
00222     int             read( void );
00223 
00224     /** Polarity setting
00225      *
00226      *  @param bit_pattern  16-bit polarity setting pattern for port1 and port0.
00227      *    If the bit is set to '1', the state will be inverted.
00228      *    (Default state is all '0')
00229      *
00230      *  @see configure()
00231      */
00232     void            polarity( int bit_pattern );
00233 
00234     /** Set IO congiguration
00235      *
00236      *  @param bit_pattern  16-bit IO direction setting pattern for port1 and port0.
00237      *
00238      *  @note
00239      *    The data for pins, given as integer.
00240      *    The 16-bit MSB goes to P1_7 pin and LSB goes to P0_0 pin.
00241      *    If the bit is set to '1', the pin will be input.
00242      *
00243      *  @see write()
00244      *  @see read()
00245      */
00246     void            configure( int bit_pattern );
00247 
00248     /** Set interrupt mask
00249      *
00250      *  @param bit_pattern  16-bit interrupt mask
00251      *
00252      *  @see interrupt_status()
00253      */
00254     void            interrupt_mask( int bit_pattern );
00255 
00256     /** Read interrupt status
00257      *
00258      *  @return
00259      *    16-bit data from interrupt status registers
00260      *
00261      *  @see interrupt_status()
00262      */
00263     int             interrupt_status( void );
00264 
00265     /** A shorthand for read()
00266      */
00267     operator int( void );
00268 
00269 #endif
00270 
00271     /** Write 16-bit data into registers
00272      *
00273      *  @param reg_index    
00274      *    RegisterIndex (like InputPort, OutoutPort, ConfigurationPort, etc.)
00275      *  @param data  16-bit data. Data will be written into the pair of 8-bit 
00276      *    registers.
00277      */
00278     virtual void    reg_index_write( char register_index, int data );
00279 
00280     /** Read 16-bit data from registers
00281      *
00282      *  @param reg_index
00283      *    RegisterIndex (like InputPort, OutoutPort, ConfigurationPort, etc.)
00284      *
00285      *  @return
00286      *    16-bit data from each pair of registers.
00287      *    The register which has lower address will be upper 8-bit data.
00288      */
00289     virtual int     reg_index_read( char register_index );
00290 
00291     /** A shorthand for write()
00292      */
00293     PCAL6416&       operator= ( int bit_pattern );
00294     PCAL6416&       operator= ( PCAL6416& rhs );
00295 
00296 private:
00297     /** Register index name */
00298     enum RegisterIndex {
00299         InputPort               = InputPort0,
00300         OutoutPort              = OutoutPort0,
00301         PolarityInversionPort   = PolarityInversionPort0,
00302         ConfigurationPort       = ConfigurationPort0,
00303         OutputDriveStrength0    = OutputDriveStrength0_0,
00304         OutputDriveStrength1    = OutputDriveStrength1_0,
00305         InputLatch              = InputLatch0,
00306         PullUpPullDowmEnable    = PullUpPullDowmEnable0,
00307         PullUpPullDowmSelection = PullUpPullDowmSelection0,
00308         InterruptMask           = InterruptMask0,
00309         InterruptStatus         = InterruptStatus0
00310     };
00311 
00312     static const char   regmap[];
00313     const int           n_of_pins;
00314 }
00315 ;
00316 
00317 #endif  //  MBED_PCAL6416