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.

This is a copy of the PCA9555 library by Akifumi "Tedd" OKANO, which is compatible with PCAL6416A chip.

Revision:
0:035111d3d631
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/base_classes/PCAL955x.cpp	Wed Feb 15 10:07:59 2017 +0000
@@ -0,0 +1,135 @@
+#include    "mbed.h"
+#include    "PCAL955x.h"
+
+PCAL955x::PCAL955x( PinName i2c_sda, PinName i2c_scl, char i2c_address )
+    :   i2c_p( new I2C( i2c_sda, i2c_scl ) ),
+        i2c( *i2c_p ),
+        address( i2c_address ),
+        pin_state( ~0x0 ),
+        pin_direction( ~0x0 )
+{
+}
+
+PCAL955x::PCAL955x( I2C &i2c_, char i2c_address )
+    :   i2c_p( NULL ),
+        i2c( i2c_ ),
+        address( i2c_address ),
+        pin_state( ~0x0 ),
+        pin_direction( ~0x0 )
+{
+}
+
+PCAL955x::~PCAL955x()
+{
+    if ( NULL != i2c_p )
+        delete  i2c_p;
+}
+
+void PCAL955x::write( int bit_pattern )
+{
+    pin_state   = bit_pattern;
+    reg_index_write( OUTPUT, pin_state );
+}
+
+int PCAL955x::read( void )
+{
+    return ( reg_index_read( INPUT ) );
+}
+
+void PCAL955x::polarity( int bit_pattern )
+{
+    reg_index_write( POLARITY, pin_direction );
+}
+
+void PCAL955x::configure( int bit_pattern )
+{
+    pin_direction   = bit_pattern;
+    reg_index_write( CONFIG, pin_direction );
+}
+
+void PCAL955x::write_with_mask( int bitpattern, int mask_bits )
+{
+    pin_state   &= (bitpattern |  mask_bits);
+    pin_state   |= (bitpattern & ~mask_bits);
+
+    write( pin_state );
+}
+
+void PCAL955x::configure_with_mask( int bitpattern, int mask_bits )
+{
+    pin_direction   &= (bitpattern |  mask_bits);
+    pin_direction   |= (bitpattern & ~mask_bits);
+
+    configure( pin_direction );
+}
+
+void PCAL955x::interrupt_mask( int bit_pattern )
+{
+    int     new_config;
+
+    new_config  = (~bit_pattern) | reg_index_read( CONFIG );
+    reg_index_write( CONFIG, new_config );
+    reg_index_write( INT_MASK, bit_pattern );
+}
+
+int PCAL955x::interrupt_status( void )
+{
+    return ( reg_index_read( INT_STAT ) );
+}
+
+
+void PCAL955x::bus_write( char *dp, int length )
+{
+#if 0
+    printf( "bus_write: 0x%02X - ", address );
+    for ( int i = 0; i < length; i++ )
+        printf( " 0x%02X", *(dp + i)  );
+    printf( "\r\n" );
+#endif
+
+    i2c.write( address, dp, length );
+}
+
+void PCAL955x::bus_read( char reg_addr, char *dp, int length )
+{
+    i2c.write( address, (char *)(&reg_addr), 1, true );
+    i2c.read(  address, dp, length );
+}
+
+void PCAL955x::write( int pin, int v )
+{
+    if ( pin < number_of_pins() ) {
+        if ( v )
+            pin_state   |= 0x01 << pin;
+        else
+            pin_state   &= ~(0x01 << pin);
+    } else {
+        pin_state   = v ? ~0x0 : 0x0;
+    }
+
+    write( pin_state );
+}
+
+int PCAL955x::read( int pin )
+{
+    return ( (reg_index_read( INPUT ) >> pin) & 0x1 );
+}
+
+void PCAL955x::configure( int pin, int v )
+{
+    if ( pin < number_of_pins() ) {
+        if ( v )
+            pin_direction   |= 0x01 << pin;
+        else
+            pin_direction   &= ~(0x01 << pin);
+    } else {
+        pin_direction   = v ? ~0x0 : 0x0;
+    }
+
+    configure( pin_direction );
+}
+
+PCAL955x::operator int( void )
+{
+    return( read() );
+}