Library for MAX7300 GPIO Expander
Revision 1:e1ee2549a047, committed 2015-07-16
- Comitter:
- j3
- Date:
- Thu Jul 16 21:27:05 2015 +0000
- Parent:
- 0:350a850a7191
- Child:
- 2:fd2de5d21702
- Commit message:
- Finished library, ready for review.
Changed in this revision
| max7300.cpp | Show annotated file Show diff for this revision Revisions of this file |
| max7300.h | Show annotated file Show diff for this revision Revisions of this file |
--- 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;
}
-
-
-
--- a/max7300.h Wed Jul 15 15:10:04 2015 +0000
+++ b/max7300.h Thu Jul 16 21:27:05 2015 +0000
@@ -10,7 +10,6 @@
* Updated:
*
* @brief Header file for Max7300 class
-*
***********************************************************************
* Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
*
@@ -116,53 +115,6 @@
}max7300_port_number_t;
- typedef enum
- {
- MAX7300_NO_OP = 0,
- MAX7300_CONFIGURATION = 4,
- MAX7300_MASK = 6,
- MAX7300_PORT_CONFIG_P07_P04 = 9,
- MAX7300_PORT_CONFIG_P11_P8,
- MAX7300_PORT_CONFIG_P15_P12,
- MAX7300_PORT_CONFIG_P19_P16,
- MAX7300_PORT_CONFIG_P23_P20,
- MAX7300_PORT_CONFIG_P27_P24,
- MAX7300_PORT_CONFIG_P31_P28,
- MAX7300_PORT_04_DATA = 0x24,
- MAX7300_PORT_05_DATA,
- MAX7300_PORT_06_DATA,
- MAX7300_PORT_07_DATA,
- MAX7300_PORT_08_DATA,
- MAX7300_PORT_09_DATA,
- MAX7300_PORT_10_DATA,
- MAX7300_PORT_11_DATA,
- MAX7300_PORT_12_DATA,
- MAX7300_PORT_13_DATA,
- MAX7300_PORT_14_DATA,
- MAX7300_PORT_15_DATA,
- MAX7300_PORT_16_DATA,
- MAX7300_PORT_17_DATA,
- MAX7300_PORT_18_DATA,
- MAX7300_PORT_19_DATA,
- MAX7300_PORT_20_DATA,
- MAX7300_PORT_21_DATA,
- MAX7300_PORT_22_DATA,
- MAX7300_PORT_23_DATA,
- MAX7300_PORT_24_DATA,
- MAX7300_PORT_25_DATA,
- MAX7300_PORT_26_DATA,
- MAX7300_PORT_27_DATA,
- MAX7300_PORT_28_DATA,
- MAX7300_PORT_29_DATA,
- MAX7300_PORT_30_DATA,
- MAX7300_PORT_31_DATA,
- MAX7300_8_PORTS_P04_P11_DATA = 0x44,
- MAX7300_8_PORTS_P12_P19_DATA = 0x4C,
- MAX7300_8_PORTS_P20_P27_DATA = 0x54,
- MAX7300_8_PORTS_P24_P31_DATA = 0x58
- }max7300_registers_t;
-
-
/**********************************************************//**
* @brief Constructor for Max7300 Class.
*
@@ -235,6 +187,32 @@
/**********************************************************//**
+ * @brief Enables Transition Detection
+ *
+ * @details Sets 'M' bit of configuration register
+ *
+ * On Entry:
+ *
+ * On Exit:
+ * @return 0 on success, non-0 on failure
+ **************************************************************/
+ int16_t enable_transition_detection(void);
+
+
+ /**********************************************************//**
+ * @brief Disables Transition Detection
+ *
+ * @details Clears 'M' bit of configuration register
+ *
+ * On Entry:
+ *
+ * On Exit:
+ * @return 0 on success, non-0 on failure
+ **************************************************************/
+ int16_t disable_transition_detection(void);
+
+
+ /**********************************************************//**
* @brief Configures a single MAX7300 GPIO port
*
* @details Configures MAX7300 GPIO port as either an output,
@@ -259,14 +237,8 @@
* @details Allows user to configure 4 ports at a time
*
* On Entry:
- * @param[in] reg - One of the following 7 registers
- * MAX7300_PORT_CONFIG_P7_P4,
- * MAX7300_PORT_CONFIG_P11_P8,
- * MAX7300_PORT_CONFIG_P15_P12,
- * MAX7300_PORT_CONFIG_P19_P16,
- * MAX7300_PORT_CONFIG_P23_P20,
- * MAX7300_PORT_CONFIG_P27_P24,
- * MAX7300_PORT_CONFIG_P31_P28
+ * @param[in] low_port - lowest of 4 ports to configure,
+ * on 4 port boundaries as in datasheet
*
* @param[in] data - Byte with each ports desired type with
* the following format - xx|xx|xx|xx
@@ -274,7 +246,24 @@
* On Exit:
* @return 0 on success, non-0 on failure
**************************************************************/
- int16_t config_ports(max7300_registers_t reg, uint8_t data);
+ int16_t config_4_ports(max7300_port_number_t low_port, uint8_t data);
+
+
+ /**********************************************************//**
+ * @brief Configures all MAX7300 GPIO ports
+ *
+ * @details Allows user to configure all ports to a single type
+ *
+ * On Entry:
+ * @param[in] port_type - One of the following port types
+ * MAX7300_PORT_OUTPUT
+ * MAX7300_PORT_INPUT
+ * MAX7300_PORT_INPUT_PULLUP
+ *
+ * On Exit:
+ * @return 0 on success, non-0 on failure
+ **************************************************************/
+ int16_t config_all_ports(max7300_port_type_t port_type);
/**********************************************************//**
@@ -283,9 +272,10 @@
* @details
*
* On Entry:
+ * @param[in] port_num - MAX7300 port number to read
*
* On Exit:
- * @return state of port, or
+ * @return state of port, or -1 on failure
**************************************************************/
int16_t read_port(max7300_port_number_t port_num);
@@ -296,9 +286,11 @@
* @details
*
* On Entry:
+ * @param[in] port_num - MAX7300 port to write
+ * @param[in] data - lsb of byte is written to port
*
* On Exit:
- * @return none
+ * @return 0 on success, non-0 on failure
**************************************************************/
int16_t write_port(max7300_port_number_t port_num, uint8_t data);
@@ -309,11 +301,14 @@
* @details
*
* On Entry:
+ * @param[in] low_port - lowest port of 8 ports to read,
+ * on 8 port boundaries as in datasheet.
+ * Max is port 24
*
* On Exit:
- * @return none
+ * @return state of ports, or -1 on failure
**************************************************************/
- int16_t read_eight_ports(max7300_registers_t reg);
+ int16_t read_8_ports(max7300_port_number_t low_port);
/**********************************************************//**
@@ -322,23 +317,48 @@
* @details
*
* On Entry:
+ * @param[in] low_port - lowest port of 8 ports to write,
+ * on 8 port boundaries as in datasheet.
+ * Max is port 24
+ *
+ * @param[in] data - Data is written to ports
*
* On Exit:
- * @return none
+ * @return 0 on success, non-0 on failure
**************************************************************/
- int16_t write_eight_ports(max7300_registers_t reg, uint8_t data);
+ int16_t write_8_ports(max7300_port_number_t low_port, uint8_t data);
+
+
+ /**********************************************************//**
+ * @brief Read transition detection mask register
+ *
+ * @details See page 11 of DS, right hand side column, paragraph 2
+ * for details on one-shot event.
+ *
+ * On Entry:
+ * @param[in] enable_snapshot - true to re-enable transition
+ * detection
+ *
+ * On Exit:
+ * @return contents of mask register, or -1 on failure
+ **************************************************************/
+ int16_t read_mask_register(bool enable_snapshot);
/**********************************************************//**
- * @brief
+ * @brief Write transition detection mask register
*
- * @details
+ * @details Enables transition detection on Ports 30-24
+ *
*
* On Entry:
+ * @param[in] data - Bits to set
*
* On Exit:
- * @return none
+ * @return 0 on success, non-0 on failure
**************************************************************/
+ int16_t write_mask_register(uint8_t data);
+
private:
@@ -346,5 +366,21 @@
bool _i2c_owner;
uint8_t _w_adrs;
uint8_t _r_adrs;
+
+
+ /**********************************************************//**
+ * @brief Write MAX7300 configuration register
+ *
+ * @details
+ *
+ * On Entry:
+ * @param[in] set_clear - If true set bit defined by data
+ *
+ * @param[in] data - 'S' or 'M' bit of configuration register
+ *
+ * On Exit:
+ * @return 0 on success, non-0 on failure
+ **************************************************************/
+ int16_t write_config_register(bool set_clear, uint8_t data);
};
#endif /* MAX7300_H*/
\ No newline at end of file