Library for MAX7300 GPIO Expander
Diff: max7300.cpp
- Revision:
- 1:e1ee2549a047
- Parent:
- 0:350a850a7191
- Child:
- 3:e044960e516c
--- a/max7300.cpp Wed Jul 15 15:10:04 2015 +0000 +++ b/max7300.cpp Thu Jul 16 21:27:05 2015 +0000 @@ -46,6 +46,20 @@ #include "max7300.h" +//configuration register bits +#define MAX7300_S_BIT 0x01 +#define MAX7300_M_BIT 0x80 + +//registers +#define MAX7300_CONFIGURATION 0x04 +#define MAX7300_TRANSITION_DETECT_MASK 0x06 +#define MAX7300_PORT_CONFIGURATION 0x09 +#define MAX7300_PORT_ONLY_BASE_ADRS 0x20 + +//helper for calclating register addresses in 8 port wide fxs +#define MAX7300_8_PORTS_OFFSET 0x40 + + //********************************************************************* Max7300::Max7300(I2C *i2c_bus, max7300_i2c_adrs_t i2c_adrs): _p_i2c(i2c_bus) { @@ -81,24 +95,8 @@ int16_t Max7300::enable_ports(void) { int16_t result = -1; - char data[] = {MAX7300_CONFIGURATION, 0}; - //set internal register pointer to configuration register - result = _p_i2c->write(_w_adrs, data, 1, true); - if(!result) - { - //get current configuration register - result = _p_i2c->read(_w_adrs, (data +1 ), 1, true); - - if(!result) - { - //set 'S' bit - data[1] |= 0x01; - - //write back to device - result = result = _p_i2c->write(_w_adrs, data, 2, false); - } - } + result = write_config_register(true, MAX7300_S_BIT); return result; } @@ -108,24 +106,30 @@ int16_t Max7300::disable_ports(void) { int16_t result = -1; - char data[] = {MAX7300_CONFIGURATION, 0}; + + result = write_config_register(false, MAX7300_S_BIT); + + return result; +} + + +//********************************************************************* +int16_t Max7300::enable_transition_detection(void) +{ + int16_t result = -1; - //set internal register pointer to configuration register - result = _p_i2c->write(_w_adrs, data, 1, true); - if(!result) - { - //get current configuration register - result = _p_i2c->read(_w_adrs, (data +1 ), 1, true); - - if(!result) - { - //clear 'S' bit - data[1] &= ~0x01; - - //write back to device - result = result = _p_i2c->write(_w_adrs, data, 2, false); - } - } + result = write_config_register(true, MAX7300_M_BIT); + + return result; +} + + +//********************************************************************* +int16_t Max7300::disable_transition_detection(void) +{ + int16_t result = -1; + + result = write_config_register(false, MAX7300_M_BIT); return result; } @@ -136,9 +140,10 @@ { int16_t result = -1; char data[2]; + uint8_t cnt = 0; //get address of port configuration register - data[0] = ((port_num/4) + 8); + data[cnt++] = ((port_num/4) + 8); //get port config bits offset in that register uint8_t offset = (port_num % 4); @@ -148,17 +153,17 @@ if(!result) { //get current port configuration register - result = _p_i2c->read(_w_adrs, (data +1 ), 1, true); + result = _p_i2c->read(_w_adrs, (data + 1), 1, true); if(!result) { - //clear old port configuration - data[1] &= ~(0x03 << (offset*2)); + //clear old port configuration, do not increment count + data[cnt] &= ~(0x03 << (offset*2)); //set port configuration bits - data[1] |= ((port_type & 0x03) << (offset*2)); + data[cnt++] |= ((port_type & 0x03) << (offset*2)); //write back to device - result = result = _p_i2c->write(_w_adrs, data, 2, false); + result = _p_i2c->write(_w_adrs, data, cnt, false); } } @@ -167,15 +172,48 @@ //********************************************************************* -int16_t Max7300::config_ports(max7300_registers_t reg, uint8_t data) +int16_t Max7300::config_4_ports(max7300_port_number_t low_port, uint8_t data) { int16_t result = -1; - char local_data[] = {reg, data}; + char local_data[2]; + uint8_t cnt = 0; + + if(low_port <= MAX7300_PORT_28) + { + if((low_port % 4) == 0) + { + local_data[cnt++] = ((low_port/4) + 8); + local_data[cnt++] = data; + + //no need for read, modify, write. + //Fx is intended to write whole register + result = _p_i2c->write(_w_adrs, local_data, cnt, false); + } + } - //no need for read, modify, write. - //Fx is intended to write whole register - result = _p_i2c->write(_w_adrs, local_data, 2, false); + return result; +} + +//********************************************************************* +int16_t Max7300::config_all_ports(max7300_port_type_t port_type) +{ + int16_t result = -1; + char data[8]; + char local_type = 0; + uint8_t cnt = 0; + //build byte for each port configuration register + local_type = ((port_type << 6) | (port_type << 4) | (port_type << 2) | port_type); + + //stuff packet + data[cnt++] = MAX7300_PORT_CONFIGURATION; + for(/**/;cnt < 8; cnt++) + { + data[cnt] = local_type; + } + + result = _p_i2c->write(_w_adrs, data, cnt, false); + return result; } @@ -186,14 +224,14 @@ int16_t result = -1; char data[2]; - data[0] = (port_num + 0x20); + data[0] = (port_num + MAX7300_PORT_ONLY_BASE_ADRS); //set internal register pointer to port data register result = _p_i2c->write(_w_adrs, data, 1, true); if(!result) { //get port data - result = _p_i2c->read(_w_adrs, (data +1 ), 1, false); + result = _p_i2c->read(_w_adrs, (data + 1), 1, false); if(!result) { result = data[1]; @@ -212,56 +250,164 @@ int16_t Max7300::write_port(max7300_port_number_t port_num, uint8_t data) { int16_t result = -1; - char local_data[] = {(port_num + 0x20), data}; + char local_data[2]; + uint8_t cnt = 0; + + local_data[cnt++] = (port_num + MAX7300_PORT_ONLY_BASE_ADRS); + local_data[cnt++] = data; //no need for read, modify, write. //Fx is intended to write whole register - result = _p_i2c->write(_w_adrs, local_data, 2, false); + result = _p_i2c->write(_w_adrs, local_data, cnt, false); + + return result; +} + + +//********************************************************************* +int16_t Max7300::read_8_ports(max7300_port_number_t low_port) +{ + int16_t result = -1; + char data[2]; + + if((low_port >= MAX7300_PORT_04) && (low_port <= MAX7300_PORT_24)) + { + data[0] = low_port + MAX7300_8_PORTS_OFFSET; + + //set internal register pointer to port data register + result = _p_i2c->write(_w_adrs, data, 1, true); + if(!result) + { + //get port data + result = _p_i2c->read(_w_adrs, (data + 1), 1, false); + if(!result) + { + result = data[1]; + } + else + { + result = -1; + } + } + } + + return result; +} + + +//********************************************************************* +int16_t Max7300::write_8_ports(max7300_port_number_t low_port, uint8_t data) +{ + int16_t result = -1; + char local_data[2]; + uint8_t cnt = 0; + + if(low_port <= MAX7300_PORT_24) + { + local_data[cnt++] = low_port + MAX7300_8_PORTS_OFFSET; + local_data[cnt++] = data; + + //no need for read, modify, write. + //Fx is intended to write whole register + result = _p_i2c->write(_w_adrs, local_data, cnt, false); + } return result; } //********************************************************************* -int16_t Max7300::read_eight_ports(max7300_registers_t reg) +int16_t Max7300::read_mask_register(bool enable_snapshot) { int16_t result = -1; char data[2]; - data[0] = reg; + data[0] = MAX7300_TRANSITION_DETECT_MASK; - //set internal register pointer to port data register + //set internal register pointer to mask register result = _p_i2c->write(_w_adrs, data, 1, true); if(!result) { - //get port data - result = _p_i2c->read(_w_adrs, (data +1 ), 1, false); + //get mask data + result = _p_i2c->read(_w_adrs, (data + 1), 1, false); if(!result) { - result = data[1]; + if(enable_snapshot) + { + result = enable_transition_detection(); + if(!result) + { + result = data[1]; + } + else + { + result = -1; + } + } + else + { + result = data[1]; + } } else { result = -1; } } - + + return result; +} + + +//********************************************************************* +int16_t Max7300::write_mask_register(uint8_t data) +{ + int16_t result = -1; + char local_data[2]; + uint8_t cnt = 0; + + local_data[cnt++] = MAX7300_TRANSITION_DETECT_MASK; + local_data[cnt++] = data; + + //no need for read, modify, write. + //Fx is intended to write whole register + result = _p_i2c->write(_w_adrs, local_data, cnt, false); + return result; } //********************************************************************* -int16_t Max7300::write_eight_ports(max7300_registers_t reg, uint8_t data) +int16_t Max7300::write_config_register(bool set_clear, uint8_t data) { int16_t result = -1; - char local_data[] = {reg, data}; + char local_data[2]; + uint8_t cnt = 0; + + local_data[cnt++] = MAX7300_CONFIGURATION; - //no need for read, modify, write. - //Fx is intended to write whole register - result = _p_i2c->write(_w_adrs, local_data, 2, false); - + //set internal register pointer to configuration register + result = _p_i2c->write(_w_adrs, local_data, 1, true); + if(!result) + { + //get current configuration register + result = _p_i2c->read(_w_adrs, (local_data + 1), 1, true); + + if(!result) + { + if(set_clear) + { + local_data[cnt++] |= data; + } + else + { + local_data[cnt++] &= ~data; + } + + //write back to device + result = _p_i2c->write(_w_adrs, local_data, cnt, false); + } + } + return result; } - - -