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.
Diff: base_classes/PCAL955x.cpp
- 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 *)(®_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() ); +}