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.
base_classes/PCAL955x.cpp@0:035111d3d631, 2017-02-15 (annotated)
- Committer:
- andriym
- Date:
- Wed Feb 15 10:07:59 2017 +0000
- Revision:
- 0:035111d3d631
A change of name for the PCAL955x library to make it searchable for people needing PCAL6416A library.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andriym | 0:035111d3d631 | 1 | #include "mbed.h" |
andriym | 0:035111d3d631 | 2 | #include "PCAL955x.h" |
andriym | 0:035111d3d631 | 3 | |
andriym | 0:035111d3d631 | 4 | PCAL955x::PCAL955x( PinName i2c_sda, PinName i2c_scl, char i2c_address ) |
andriym | 0:035111d3d631 | 5 | : i2c_p( new I2C( i2c_sda, i2c_scl ) ), |
andriym | 0:035111d3d631 | 6 | i2c( *i2c_p ), |
andriym | 0:035111d3d631 | 7 | address( i2c_address ), |
andriym | 0:035111d3d631 | 8 | pin_state( ~0x0 ), |
andriym | 0:035111d3d631 | 9 | pin_direction( ~0x0 ) |
andriym | 0:035111d3d631 | 10 | { |
andriym | 0:035111d3d631 | 11 | } |
andriym | 0:035111d3d631 | 12 | |
andriym | 0:035111d3d631 | 13 | PCAL955x::PCAL955x( I2C &i2c_, char i2c_address ) |
andriym | 0:035111d3d631 | 14 | : i2c_p( NULL ), |
andriym | 0:035111d3d631 | 15 | i2c( i2c_ ), |
andriym | 0:035111d3d631 | 16 | address( i2c_address ), |
andriym | 0:035111d3d631 | 17 | pin_state( ~0x0 ), |
andriym | 0:035111d3d631 | 18 | pin_direction( ~0x0 ) |
andriym | 0:035111d3d631 | 19 | { |
andriym | 0:035111d3d631 | 20 | } |
andriym | 0:035111d3d631 | 21 | |
andriym | 0:035111d3d631 | 22 | PCAL955x::~PCAL955x() |
andriym | 0:035111d3d631 | 23 | { |
andriym | 0:035111d3d631 | 24 | if ( NULL != i2c_p ) |
andriym | 0:035111d3d631 | 25 | delete i2c_p; |
andriym | 0:035111d3d631 | 26 | } |
andriym | 0:035111d3d631 | 27 | |
andriym | 0:035111d3d631 | 28 | void PCAL955x::write( int bit_pattern ) |
andriym | 0:035111d3d631 | 29 | { |
andriym | 0:035111d3d631 | 30 | pin_state = bit_pattern; |
andriym | 0:035111d3d631 | 31 | reg_index_write( OUTPUT, pin_state ); |
andriym | 0:035111d3d631 | 32 | } |
andriym | 0:035111d3d631 | 33 | |
andriym | 0:035111d3d631 | 34 | int PCAL955x::read( void ) |
andriym | 0:035111d3d631 | 35 | { |
andriym | 0:035111d3d631 | 36 | return ( reg_index_read( INPUT ) ); |
andriym | 0:035111d3d631 | 37 | } |
andriym | 0:035111d3d631 | 38 | |
andriym | 0:035111d3d631 | 39 | void PCAL955x::polarity( int bit_pattern ) |
andriym | 0:035111d3d631 | 40 | { |
andriym | 0:035111d3d631 | 41 | reg_index_write( POLARITY, pin_direction ); |
andriym | 0:035111d3d631 | 42 | } |
andriym | 0:035111d3d631 | 43 | |
andriym | 0:035111d3d631 | 44 | void PCAL955x::configure( int bit_pattern ) |
andriym | 0:035111d3d631 | 45 | { |
andriym | 0:035111d3d631 | 46 | pin_direction = bit_pattern; |
andriym | 0:035111d3d631 | 47 | reg_index_write( CONFIG, pin_direction ); |
andriym | 0:035111d3d631 | 48 | } |
andriym | 0:035111d3d631 | 49 | |
andriym | 0:035111d3d631 | 50 | void PCAL955x::write_with_mask( int bitpattern, int mask_bits ) |
andriym | 0:035111d3d631 | 51 | { |
andriym | 0:035111d3d631 | 52 | pin_state &= (bitpattern | mask_bits); |
andriym | 0:035111d3d631 | 53 | pin_state |= (bitpattern & ~mask_bits); |
andriym | 0:035111d3d631 | 54 | |
andriym | 0:035111d3d631 | 55 | write( pin_state ); |
andriym | 0:035111d3d631 | 56 | } |
andriym | 0:035111d3d631 | 57 | |
andriym | 0:035111d3d631 | 58 | void PCAL955x::configure_with_mask( int bitpattern, int mask_bits ) |
andriym | 0:035111d3d631 | 59 | { |
andriym | 0:035111d3d631 | 60 | pin_direction &= (bitpattern | mask_bits); |
andriym | 0:035111d3d631 | 61 | pin_direction |= (bitpattern & ~mask_bits); |
andriym | 0:035111d3d631 | 62 | |
andriym | 0:035111d3d631 | 63 | configure( pin_direction ); |
andriym | 0:035111d3d631 | 64 | } |
andriym | 0:035111d3d631 | 65 | |
andriym | 0:035111d3d631 | 66 | void PCAL955x::interrupt_mask( int bit_pattern ) |
andriym | 0:035111d3d631 | 67 | { |
andriym | 0:035111d3d631 | 68 | int new_config; |
andriym | 0:035111d3d631 | 69 | |
andriym | 0:035111d3d631 | 70 | new_config = (~bit_pattern) | reg_index_read( CONFIG ); |
andriym | 0:035111d3d631 | 71 | reg_index_write( CONFIG, new_config ); |
andriym | 0:035111d3d631 | 72 | reg_index_write( INT_MASK, bit_pattern ); |
andriym | 0:035111d3d631 | 73 | } |
andriym | 0:035111d3d631 | 74 | |
andriym | 0:035111d3d631 | 75 | int PCAL955x::interrupt_status( void ) |
andriym | 0:035111d3d631 | 76 | { |
andriym | 0:035111d3d631 | 77 | return ( reg_index_read( INT_STAT ) ); |
andriym | 0:035111d3d631 | 78 | } |
andriym | 0:035111d3d631 | 79 | |
andriym | 0:035111d3d631 | 80 | |
andriym | 0:035111d3d631 | 81 | void PCAL955x::bus_write( char *dp, int length ) |
andriym | 0:035111d3d631 | 82 | { |
andriym | 0:035111d3d631 | 83 | #if 0 |
andriym | 0:035111d3d631 | 84 | printf( "bus_write: 0x%02X - ", address ); |
andriym | 0:035111d3d631 | 85 | for ( int i = 0; i < length; i++ ) |
andriym | 0:035111d3d631 | 86 | printf( " 0x%02X", *(dp + i) ); |
andriym | 0:035111d3d631 | 87 | printf( "\r\n" ); |
andriym | 0:035111d3d631 | 88 | #endif |
andriym | 0:035111d3d631 | 89 | |
andriym | 0:035111d3d631 | 90 | i2c.write( address, dp, length ); |
andriym | 0:035111d3d631 | 91 | } |
andriym | 0:035111d3d631 | 92 | |
andriym | 0:035111d3d631 | 93 | void PCAL955x::bus_read( char reg_addr, char *dp, int length ) |
andriym | 0:035111d3d631 | 94 | { |
andriym | 0:035111d3d631 | 95 | i2c.write( address, (char *)(®_addr), 1, true ); |
andriym | 0:035111d3d631 | 96 | i2c.read( address, dp, length ); |
andriym | 0:035111d3d631 | 97 | } |
andriym | 0:035111d3d631 | 98 | |
andriym | 0:035111d3d631 | 99 | void PCAL955x::write( int pin, int v ) |
andriym | 0:035111d3d631 | 100 | { |
andriym | 0:035111d3d631 | 101 | if ( pin < number_of_pins() ) { |
andriym | 0:035111d3d631 | 102 | if ( v ) |
andriym | 0:035111d3d631 | 103 | pin_state |= 0x01 << pin; |
andriym | 0:035111d3d631 | 104 | else |
andriym | 0:035111d3d631 | 105 | pin_state &= ~(0x01 << pin); |
andriym | 0:035111d3d631 | 106 | } else { |
andriym | 0:035111d3d631 | 107 | pin_state = v ? ~0x0 : 0x0; |
andriym | 0:035111d3d631 | 108 | } |
andriym | 0:035111d3d631 | 109 | |
andriym | 0:035111d3d631 | 110 | write( pin_state ); |
andriym | 0:035111d3d631 | 111 | } |
andriym | 0:035111d3d631 | 112 | |
andriym | 0:035111d3d631 | 113 | int PCAL955x::read( int pin ) |
andriym | 0:035111d3d631 | 114 | { |
andriym | 0:035111d3d631 | 115 | return ( (reg_index_read( INPUT ) >> pin) & 0x1 ); |
andriym | 0:035111d3d631 | 116 | } |
andriym | 0:035111d3d631 | 117 | |
andriym | 0:035111d3d631 | 118 | void PCAL955x::configure( int pin, int v ) |
andriym | 0:035111d3d631 | 119 | { |
andriym | 0:035111d3d631 | 120 | if ( pin < number_of_pins() ) { |
andriym | 0:035111d3d631 | 121 | if ( v ) |
andriym | 0:035111d3d631 | 122 | pin_direction |= 0x01 << pin; |
andriym | 0:035111d3d631 | 123 | else |
andriym | 0:035111d3d631 | 124 | pin_direction &= ~(0x01 << pin); |
andriym | 0:035111d3d631 | 125 | } else { |
andriym | 0:035111d3d631 | 126 | pin_direction = v ? ~0x0 : 0x0; |
andriym | 0:035111d3d631 | 127 | } |
andriym | 0:035111d3d631 | 128 | |
andriym | 0:035111d3d631 | 129 | configure( pin_direction ); |
andriym | 0:035111d3d631 | 130 | } |
andriym | 0:035111d3d631 | 131 | |
andriym | 0:035111d3d631 | 132 | PCAL955x::operator int( void ) |
andriym | 0:035111d3d631 | 133 | { |
andriym | 0:035111d3d631 | 134 | return( read() ); |
andriym | 0:035111d3d631 | 135 | } |