Library for MAX7300 GPIO Expander
Embed:
(wiki syntax)
Show/hide line numbers
max7300.cpp
Go to the documentation of this file.
00001 /******************************************************************//** 00002 * @file max7300.cpp 00003 * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved. 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining a 00006 * copy of this software and associated documentation files (the "Software"), 00007 * to deal in the Software without restriction, including without limitation 00008 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00009 * and/or sell copies of the Software, and to permit persons to whom the 00010 * Software is furnished to do so, subject to the following conditions: 00011 * 00012 * The above copyright notice and this permission notice shall be included 00013 * in all copies or substantial portions of the Software. 00014 * 00015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00016 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00017 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00018 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00019 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00020 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00021 * OTHER DEALINGS IN THE SOFTWARE. 00022 * 00023 * Except as contained in this notice, the name of Maxim Integrated 00024 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00025 * Products, Inc. Branding Policy. 00026 * 00027 * The mere transfer of this software does not imply any licenses 00028 * of trade secrets, proprietary technology, copyrights, patents, 00029 * trademarks, maskwork rights, or any other form of intellectual 00030 * property whatsoever. Maxim Integrated Products, Inc. retains all 00031 * ownership rights. 00032 **********************************************************************/ 00033 00034 00035 #include "max7300.h" 00036 00037 00038 //configuration register bits 00039 #define MAX7300_S_BIT (0x01) 00040 #define MAX7300_M_BIT (0x80) 00041 00042 //registers 00043 #define MAX7300_CONFIGURATION (0x04) 00044 #define MAX7300_TRANSITION_DETECT_MASK (0x06) 00045 #define MAX7300_PORT_CONFIGURATION (0x09) 00046 #define MAX7300_PORT_ONLY_BASE_ADRS (0x20) 00047 00048 //helper for calclating register addresses in 8 port wide fxs 00049 #define MAX7300_8_PORTS_OFFSET (0x40) 00050 00051 00052 //********************************************************************* 00053 Max7300::Max7300(I2C *i2c_bus, max7300_i2c_adrs_t i2c_adrs): _p_i2c(i2c_bus) 00054 { 00055 _i2c_owner = false; 00056 00057 _r_adrs = ((i2c_adrs << 1) | 1); 00058 _w_adrs = (i2c_adrs << 1); 00059 } 00060 00061 00062 //********************************************************************* 00063 Max7300::Max7300(PinName sda, PinName scl, max7300_i2c_adrs_t i2c_adrs) 00064 { 00065 _p_i2c = new I2C(sda, scl); 00066 _i2c_owner = true; 00067 00068 _r_adrs = ((i2c_adrs << 1) | 1); 00069 _w_adrs = (i2c_adrs << 1); 00070 } 00071 00072 00073 //********************************************************************* 00074 Max7300::~Max7300() 00075 { 00076 if(_i2c_owner) 00077 { 00078 delete _p_i2c; 00079 } 00080 } 00081 00082 00083 //********************************************************************* 00084 int16_t Max7300::enable_ports(void) 00085 { 00086 int16_t result = -1; 00087 00088 result = write_config_register(true, MAX7300_S_BIT); 00089 00090 return result; 00091 } 00092 00093 00094 //********************************************************************* 00095 int16_t Max7300::disable_ports(void) 00096 { 00097 int16_t result = -1; 00098 00099 result = write_config_register(false, MAX7300_S_BIT); 00100 00101 return result; 00102 } 00103 00104 00105 //********************************************************************* 00106 int16_t Max7300::enable_transition_detection(void) 00107 { 00108 int16_t result = -1; 00109 00110 result = write_config_register(true, MAX7300_M_BIT); 00111 00112 return result; 00113 } 00114 00115 00116 //********************************************************************* 00117 int16_t Max7300::disable_transition_detection(void) 00118 { 00119 int16_t result = -1; 00120 00121 result = write_config_register(false, MAX7300_M_BIT); 00122 00123 return result; 00124 } 00125 00126 00127 //********************************************************************* 00128 int16_t Max7300::config_port(max7300_port_number_t port_num, max7300_port_type_t port_type) 00129 { 00130 int16_t result = -1; 00131 char data[2]; 00132 uint8_t cnt = 0; 00133 00134 //get address of port configuration register 00135 data[cnt++] = ((port_num/4) + 8); 00136 00137 //get port config bits offset in that register 00138 uint8_t offset = (port_num % 4); 00139 00140 //set internal register pointer to port configuration register 00141 result = _p_i2c->write(_w_adrs, data, 1, true); 00142 if(!result) 00143 { 00144 //get current port configuration register 00145 result = _p_i2c->read(_r_adrs, (data + 1), 1, false); 00146 00147 if(!result) 00148 { 00149 //clear old port configuration, do not increment count 00150 data[cnt] &= ~(0x03 << (offset*2)); 00151 //set port configuration bits 00152 data[cnt++] |= ((port_type & 0x03) << (offset*2)); 00153 00154 //write back to device 00155 result = _p_i2c->write(_w_adrs, data, cnt, false); 00156 } 00157 } 00158 00159 return result; 00160 } 00161 00162 00163 //********************************************************************* 00164 int16_t Max7300::config_4_ports(max7300_port_number_t low_port, uint8_t data) 00165 { 00166 int16_t result = -1; 00167 char local_data[2]; 00168 uint8_t cnt = 0; 00169 00170 if(low_port <= MAX7300_PORT_28) 00171 { 00172 if((low_port % 4) == 0) 00173 { 00174 local_data[cnt++] = ((low_port/4) + 8); 00175 local_data[cnt++] = data; 00176 00177 //no need for read, modify, write. 00178 //Fx is intended to write whole register 00179 result = _p_i2c->write(_w_adrs, local_data, cnt, false); 00180 } 00181 } 00182 00183 return result; 00184 } 00185 00186 //********************************************************************* 00187 int16_t Max7300::config_all_ports(max7300_port_type_t port_type) 00188 { 00189 int16_t result = -1; 00190 char data[8]; 00191 char local_type = 0; 00192 uint8_t cnt = 0; 00193 00194 //build byte for each port configuration register 00195 local_type = ((port_type << 6) | (port_type << 4) | (port_type << 2) | port_type); 00196 00197 //stuff packet 00198 data[cnt++] = MAX7300_PORT_CONFIGURATION; 00199 for(/**/;cnt < 8; cnt++) 00200 { 00201 data[cnt] = local_type; 00202 } 00203 00204 result = _p_i2c->write(_w_adrs, data, cnt, false); 00205 00206 return result; 00207 } 00208 00209 00210 //********************************************************************* 00211 int16_t Max7300::read_port(max7300_port_number_t port_num) 00212 { 00213 int16_t result = -1; 00214 char data[2]; 00215 00216 data[0] = (port_num + MAX7300_PORT_ONLY_BASE_ADRS); 00217 00218 //set internal register pointer to port data register 00219 result = _p_i2c->write(_w_adrs, data, 1, true); 00220 if(!result) 00221 { 00222 //get port data 00223 result = _p_i2c->read(_r_adrs, (data + 1), 1, false); 00224 if(!result) 00225 { 00226 result = data[1]; 00227 } 00228 else 00229 { 00230 result = -1; 00231 } 00232 } 00233 00234 return result; 00235 } 00236 00237 00238 //********************************************************************* 00239 int16_t Max7300::write_port(max7300_port_number_t port_num, uint8_t data) 00240 { 00241 int16_t result = -1; 00242 char local_data[2]; 00243 uint8_t cnt = 0; 00244 00245 local_data[cnt++] = (port_num + MAX7300_PORT_ONLY_BASE_ADRS); 00246 local_data[cnt++] = data; 00247 00248 //no need for read, modify, write. 00249 //Fx is intended to write whole register 00250 result = _p_i2c->write(_w_adrs, local_data, cnt, false); 00251 00252 return result; 00253 } 00254 00255 00256 //********************************************************************* 00257 int16_t Max7300::read_8_ports(max7300_port_number_t low_port) 00258 { 00259 int16_t result = -1; 00260 char data[2]; 00261 00262 if((low_port >= MAX7300_PORT_04) && (low_port <= MAX7300_PORT_24)) 00263 { 00264 data[0] = low_port + MAX7300_8_PORTS_OFFSET; 00265 00266 //set internal register pointer to port data register 00267 result = _p_i2c->write(_w_adrs, data, 1, true); 00268 if(!result) 00269 { 00270 //get port data 00271 result = _p_i2c->read(_r_adrs, (data + 1), 1, false); 00272 if(!result) 00273 { 00274 result = data[1]; 00275 } 00276 else 00277 { 00278 result = -1; 00279 } 00280 } 00281 } 00282 00283 return result; 00284 } 00285 00286 00287 //********************************************************************* 00288 int16_t Max7300::write_8_ports(max7300_port_number_t low_port, uint8_t data) 00289 { 00290 int16_t result = -1; 00291 char local_data[2]; 00292 uint8_t cnt = 0; 00293 00294 if(low_port <= MAX7300_PORT_24) 00295 { 00296 local_data[cnt++] = low_port + MAX7300_8_PORTS_OFFSET; 00297 local_data[cnt++] = data; 00298 00299 //no need for read, modify, write. 00300 //Fx is intended to write whole register 00301 result = _p_i2c->write(_w_adrs, local_data, cnt, false); 00302 } 00303 00304 return result; 00305 } 00306 00307 00308 //********************************************************************* 00309 int16_t Max7300::read_mask_register(bool enable_snapshot) 00310 { 00311 int16_t result = -1; 00312 char data[2]; 00313 00314 data[0] = MAX7300_TRANSITION_DETECT_MASK; 00315 00316 //set internal register pointer to mask register 00317 result = _p_i2c->write(_w_adrs, data, 1, true); 00318 if(!result) 00319 { 00320 //get mask data 00321 result = _p_i2c->read(_r_adrs, (data + 1), 1, false); 00322 if(!result) 00323 { 00324 if(enable_snapshot) 00325 { 00326 result = enable_transition_detection(); 00327 if(!result) 00328 { 00329 result = data[1]; 00330 } 00331 else 00332 { 00333 result = -1; 00334 } 00335 } 00336 else 00337 { 00338 result = data[1]; 00339 } 00340 } 00341 else 00342 { 00343 result = -1; 00344 } 00345 } 00346 00347 return result; 00348 } 00349 00350 00351 //********************************************************************* 00352 int16_t Max7300::write_mask_register(uint8_t data) 00353 { 00354 int16_t result = -1; 00355 char local_data[2]; 00356 uint8_t cnt = 0; 00357 00358 local_data[cnt++] = MAX7300_TRANSITION_DETECT_MASK; 00359 local_data[cnt++] = data; 00360 00361 //no need for read, modify, write. 00362 //Fx is intended to write whole register 00363 result = _p_i2c->write(_w_adrs, local_data, cnt, false); 00364 00365 return result; 00366 } 00367 00368 00369 //********************************************************************* 00370 int16_t Max7300::write_config_register(bool set_clear, uint8_t data) 00371 { 00372 int16_t result = -1; 00373 char local_data[2]; 00374 uint8_t cnt = 0; 00375 00376 local_data[cnt++] = MAX7300_CONFIGURATION; 00377 00378 //set internal register pointer to configuration register 00379 result = _p_i2c->write(_w_adrs, local_data, 1, true); 00380 if(!result) 00381 { 00382 //get current configuration register 00383 result = _p_i2c->read(_r_adrs, (local_data + 1), 1, false); 00384 00385 if(!result) 00386 { 00387 if(set_clear) 00388 { 00389 local_data[cnt++] |= data; 00390 } 00391 else 00392 { 00393 local_data[cnt++] &= ~data; 00394 } 00395 00396 //write back to device 00397 result = _p_i2c->write(_w_adrs, local_data, cnt, false); 00398 } 00399 } 00400 00401 return result; 00402 }
Generated on Sat Jul 23 2022 21:51:19 by
1.7.2