Library for MAX7300 GPIO Expander

Dependents:   MAX14871_Shield

Committer:
j3
Date:
Thu Jul 16 21:27:05 2015 +0000
Revision:
1:e1ee2549a047
Parent:
0:350a850a7191
Child:
3:e044960e516c
Finished library, ready for review.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
j3 0:350a850a7191 1 /******************************************************************//**
j3 0:350a850a7191 2 * @file max7300.h
j3 0:350a850a7191 3 *
j3 0:350a850a7191 4 * @author Justin Jordan
j3 0:350a850a7191 5 *
j3 0:350a850a7191 6 * @version 0.0
j3 0:350a850a7191 7 *
j3 0:350a850a7191 8 * Started: 14JUL15
j3 0:350a850a7191 9 *
j3 0:350a850a7191 10 * Updated:
j3 0:350a850a7191 11 *
j3 0:350a850a7191 12 * @brief Source file for Max7300 class
j3 0:350a850a7191 13 ***********************************************************************
j3 0:350a850a7191 14 * Copyright (C) 2015 Maxim Integrated Products, Inc., All Rights Reserved.
j3 0:350a850a7191 15 *
j3 0:350a850a7191 16 * Permission is hereby granted, free of charge, to any person obtaining a
j3 0:350a850a7191 17 * copy of this software and associated documentation files (the "Software"),
j3 0:350a850a7191 18 * to deal in the Software without restriction, including without limitation
j3 0:350a850a7191 19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
j3 0:350a850a7191 20 * and/or sell copies of the Software, and to permit persons to whom the
j3 0:350a850a7191 21 * Software is furnished to do so, subject to the following conditions:
j3 0:350a850a7191 22 *
j3 0:350a850a7191 23 * The above copyright notice and this permission notice shall be included
j3 0:350a850a7191 24 * in all copies or substantial portions of the Software.
j3 0:350a850a7191 25 *
j3 0:350a850a7191 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
j3 0:350a850a7191 27 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
j3 0:350a850a7191 28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
j3 0:350a850a7191 29 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
j3 0:350a850a7191 30 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
j3 0:350a850a7191 31 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
j3 0:350a850a7191 32 * OTHER DEALINGS IN THE SOFTWARE.
j3 0:350a850a7191 33 *
j3 0:350a850a7191 34 * Except as contained in this notice, the name of Maxim Integrated
j3 0:350a850a7191 35 * Products, Inc. shall not be used except as stated in the Maxim Integrated
j3 0:350a850a7191 36 * Products, Inc. Branding Policy.
j3 0:350a850a7191 37 *
j3 0:350a850a7191 38 * The mere transfer of this software does not imply any licenses
j3 0:350a850a7191 39 * of trade secrets, proprietary technology, copyrights, patents,
j3 0:350a850a7191 40 * trademarks, maskwork rights, or any other form of intellectual
j3 0:350a850a7191 41 * property whatsoever. Maxim Integrated Products, Inc. retains all
j3 0:350a850a7191 42 * ownership rights.
j3 0:350a850a7191 43 **********************************************************************/
j3 0:350a850a7191 44
j3 0:350a850a7191 45
j3 0:350a850a7191 46 #include "max7300.h"
j3 0:350a850a7191 47
j3 0:350a850a7191 48
j3 1:e1ee2549a047 49 //configuration register bits
j3 1:e1ee2549a047 50 #define MAX7300_S_BIT 0x01
j3 1:e1ee2549a047 51 #define MAX7300_M_BIT 0x80
j3 1:e1ee2549a047 52
j3 1:e1ee2549a047 53 //registers
j3 1:e1ee2549a047 54 #define MAX7300_CONFIGURATION 0x04
j3 1:e1ee2549a047 55 #define MAX7300_TRANSITION_DETECT_MASK 0x06
j3 1:e1ee2549a047 56 #define MAX7300_PORT_CONFIGURATION 0x09
j3 1:e1ee2549a047 57 #define MAX7300_PORT_ONLY_BASE_ADRS 0x20
j3 1:e1ee2549a047 58
j3 1:e1ee2549a047 59 //helper for calclating register addresses in 8 port wide fxs
j3 1:e1ee2549a047 60 #define MAX7300_8_PORTS_OFFSET 0x40
j3 1:e1ee2549a047 61
j3 1:e1ee2549a047 62
j3 0:350a850a7191 63 //*********************************************************************
j3 0:350a850a7191 64 Max7300::Max7300(I2C *i2c_bus, max7300_i2c_adrs_t i2c_adrs): _p_i2c(i2c_bus)
j3 0:350a850a7191 65 {
j3 0:350a850a7191 66 _i2c_owner = false;
j3 0:350a850a7191 67
j3 0:350a850a7191 68 _r_adrs = ((i2c_adrs << 1) | 1);
j3 0:350a850a7191 69 _w_adrs = (i2c_adrs << 1);
j3 0:350a850a7191 70 }
j3 0:350a850a7191 71
j3 0:350a850a7191 72
j3 0:350a850a7191 73 //*********************************************************************
j3 0:350a850a7191 74 Max7300::Max7300(PinName sda, PinName scl, max7300_i2c_adrs_t i2c_adrs)
j3 0:350a850a7191 75 {
j3 0:350a850a7191 76 _p_i2c = new I2C(sda, scl);
j3 0:350a850a7191 77 _i2c_owner = true;
j3 0:350a850a7191 78
j3 0:350a850a7191 79 _r_adrs = ((i2c_adrs << 1) | 1);
j3 0:350a850a7191 80 _w_adrs = (i2c_adrs << 1);
j3 0:350a850a7191 81 }
j3 0:350a850a7191 82
j3 0:350a850a7191 83
j3 0:350a850a7191 84 //*********************************************************************
j3 0:350a850a7191 85 Max7300::~Max7300()
j3 0:350a850a7191 86 {
j3 0:350a850a7191 87 if(_i2c_owner)
j3 0:350a850a7191 88 {
j3 0:350a850a7191 89 delete _p_i2c;
j3 0:350a850a7191 90 }
j3 0:350a850a7191 91 }
j3 0:350a850a7191 92
j3 0:350a850a7191 93
j3 0:350a850a7191 94 //*********************************************************************
j3 0:350a850a7191 95 int16_t Max7300::enable_ports(void)
j3 0:350a850a7191 96 {
j3 0:350a850a7191 97 int16_t result = -1;
j3 0:350a850a7191 98
j3 1:e1ee2549a047 99 result = write_config_register(true, MAX7300_S_BIT);
j3 0:350a850a7191 100
j3 0:350a850a7191 101 return result;
j3 0:350a850a7191 102 }
j3 0:350a850a7191 103
j3 0:350a850a7191 104
j3 0:350a850a7191 105 //*********************************************************************
j3 0:350a850a7191 106 int16_t Max7300::disable_ports(void)
j3 0:350a850a7191 107 {
j3 0:350a850a7191 108 int16_t result = -1;
j3 1:e1ee2549a047 109
j3 1:e1ee2549a047 110 result = write_config_register(false, MAX7300_S_BIT);
j3 1:e1ee2549a047 111
j3 1:e1ee2549a047 112 return result;
j3 1:e1ee2549a047 113 }
j3 1:e1ee2549a047 114
j3 1:e1ee2549a047 115
j3 1:e1ee2549a047 116 //*********************************************************************
j3 1:e1ee2549a047 117 int16_t Max7300::enable_transition_detection(void)
j3 1:e1ee2549a047 118 {
j3 1:e1ee2549a047 119 int16_t result = -1;
j3 0:350a850a7191 120
j3 1:e1ee2549a047 121 result = write_config_register(true, MAX7300_M_BIT);
j3 1:e1ee2549a047 122
j3 1:e1ee2549a047 123 return result;
j3 1:e1ee2549a047 124 }
j3 1:e1ee2549a047 125
j3 1:e1ee2549a047 126
j3 1:e1ee2549a047 127 //*********************************************************************
j3 1:e1ee2549a047 128 int16_t Max7300::disable_transition_detection(void)
j3 1:e1ee2549a047 129 {
j3 1:e1ee2549a047 130 int16_t result = -1;
j3 1:e1ee2549a047 131
j3 1:e1ee2549a047 132 result = write_config_register(false, MAX7300_M_BIT);
j3 0:350a850a7191 133
j3 0:350a850a7191 134 return result;
j3 0:350a850a7191 135 }
j3 0:350a850a7191 136
j3 0:350a850a7191 137
j3 0:350a850a7191 138 //*********************************************************************
j3 0:350a850a7191 139 int16_t Max7300::config_port(max7300_port_number_t port_num, max7300_port_type_t port_type)
j3 0:350a850a7191 140 {
j3 0:350a850a7191 141 int16_t result = -1;
j3 0:350a850a7191 142 char data[2];
j3 1:e1ee2549a047 143 uint8_t cnt = 0;
j3 0:350a850a7191 144
j3 0:350a850a7191 145 //get address of port configuration register
j3 1:e1ee2549a047 146 data[cnt++] = ((port_num/4) + 8);
j3 0:350a850a7191 147
j3 0:350a850a7191 148 //get port config bits offset in that register
j3 0:350a850a7191 149 uint8_t offset = (port_num % 4);
j3 0:350a850a7191 150
j3 0:350a850a7191 151 //set internal register pointer to port configuration register
j3 0:350a850a7191 152 result = _p_i2c->write(_w_adrs, data, 1, true);
j3 0:350a850a7191 153 if(!result)
j3 0:350a850a7191 154 {
j3 0:350a850a7191 155 //get current port configuration register
j3 1:e1ee2549a047 156 result = _p_i2c->read(_w_adrs, (data + 1), 1, true);
j3 0:350a850a7191 157
j3 0:350a850a7191 158 if(!result)
j3 0:350a850a7191 159 {
j3 1:e1ee2549a047 160 //clear old port configuration, do not increment count
j3 1:e1ee2549a047 161 data[cnt] &= ~(0x03 << (offset*2));
j3 0:350a850a7191 162 //set port configuration bits
j3 1:e1ee2549a047 163 data[cnt++] |= ((port_type & 0x03) << (offset*2));
j3 0:350a850a7191 164
j3 0:350a850a7191 165 //write back to device
j3 1:e1ee2549a047 166 result = _p_i2c->write(_w_adrs, data, cnt, false);
j3 0:350a850a7191 167 }
j3 0:350a850a7191 168 }
j3 0:350a850a7191 169
j3 0:350a850a7191 170 return result;
j3 0:350a850a7191 171 }
j3 0:350a850a7191 172
j3 0:350a850a7191 173
j3 0:350a850a7191 174 //*********************************************************************
j3 1:e1ee2549a047 175 int16_t Max7300::config_4_ports(max7300_port_number_t low_port, uint8_t data)
j3 0:350a850a7191 176 {
j3 0:350a850a7191 177 int16_t result = -1;
j3 1:e1ee2549a047 178 char local_data[2];
j3 1:e1ee2549a047 179 uint8_t cnt = 0;
j3 1:e1ee2549a047 180
j3 1:e1ee2549a047 181 if(low_port <= MAX7300_PORT_28)
j3 1:e1ee2549a047 182 {
j3 1:e1ee2549a047 183 if((low_port % 4) == 0)
j3 1:e1ee2549a047 184 {
j3 1:e1ee2549a047 185 local_data[cnt++] = ((low_port/4) + 8);
j3 1:e1ee2549a047 186 local_data[cnt++] = data;
j3 1:e1ee2549a047 187
j3 1:e1ee2549a047 188 //no need for read, modify, write.
j3 1:e1ee2549a047 189 //Fx is intended to write whole register
j3 1:e1ee2549a047 190 result = _p_i2c->write(_w_adrs, local_data, cnt, false);
j3 1:e1ee2549a047 191 }
j3 1:e1ee2549a047 192 }
j3 0:350a850a7191 193
j3 1:e1ee2549a047 194 return result;
j3 1:e1ee2549a047 195 }
j3 1:e1ee2549a047 196
j3 1:e1ee2549a047 197 //*********************************************************************
j3 1:e1ee2549a047 198 int16_t Max7300::config_all_ports(max7300_port_type_t port_type)
j3 1:e1ee2549a047 199 {
j3 1:e1ee2549a047 200 int16_t result = -1;
j3 1:e1ee2549a047 201 char data[8];
j3 1:e1ee2549a047 202 char local_type = 0;
j3 1:e1ee2549a047 203 uint8_t cnt = 0;
j3 0:350a850a7191 204
j3 1:e1ee2549a047 205 //build byte for each port configuration register
j3 1:e1ee2549a047 206 local_type = ((port_type << 6) | (port_type << 4) | (port_type << 2) | port_type);
j3 1:e1ee2549a047 207
j3 1:e1ee2549a047 208 //stuff packet
j3 1:e1ee2549a047 209 data[cnt++] = MAX7300_PORT_CONFIGURATION;
j3 1:e1ee2549a047 210 for(/**/;cnt < 8; cnt++)
j3 1:e1ee2549a047 211 {
j3 1:e1ee2549a047 212 data[cnt] = local_type;
j3 1:e1ee2549a047 213 }
j3 1:e1ee2549a047 214
j3 1:e1ee2549a047 215 result = _p_i2c->write(_w_adrs, data, cnt, false);
j3 1:e1ee2549a047 216
j3 0:350a850a7191 217 return result;
j3 0:350a850a7191 218 }
j3 0:350a850a7191 219
j3 0:350a850a7191 220
j3 0:350a850a7191 221 //*********************************************************************
j3 0:350a850a7191 222 int16_t Max7300::read_port(max7300_port_number_t port_num)
j3 0:350a850a7191 223 {
j3 0:350a850a7191 224 int16_t result = -1;
j3 0:350a850a7191 225 char data[2];
j3 0:350a850a7191 226
j3 1:e1ee2549a047 227 data[0] = (port_num + MAX7300_PORT_ONLY_BASE_ADRS);
j3 0:350a850a7191 228
j3 0:350a850a7191 229 //set internal register pointer to port data register
j3 0:350a850a7191 230 result = _p_i2c->write(_w_adrs, data, 1, true);
j3 0:350a850a7191 231 if(!result)
j3 0:350a850a7191 232 {
j3 0:350a850a7191 233 //get port data
j3 1:e1ee2549a047 234 result = _p_i2c->read(_w_adrs, (data + 1), 1, false);
j3 0:350a850a7191 235 if(!result)
j3 0:350a850a7191 236 {
j3 0:350a850a7191 237 result = data[1];
j3 0:350a850a7191 238 }
j3 0:350a850a7191 239 else
j3 0:350a850a7191 240 {
j3 0:350a850a7191 241 result = -1;
j3 0:350a850a7191 242 }
j3 0:350a850a7191 243 }
j3 0:350a850a7191 244
j3 0:350a850a7191 245 return result;
j3 0:350a850a7191 246 }
j3 0:350a850a7191 247
j3 0:350a850a7191 248
j3 0:350a850a7191 249 //*********************************************************************
j3 0:350a850a7191 250 int16_t Max7300::write_port(max7300_port_number_t port_num, uint8_t data)
j3 0:350a850a7191 251 {
j3 0:350a850a7191 252 int16_t result = -1;
j3 1:e1ee2549a047 253 char local_data[2];
j3 1:e1ee2549a047 254 uint8_t cnt = 0;
j3 1:e1ee2549a047 255
j3 1:e1ee2549a047 256 local_data[cnt++] = (port_num + MAX7300_PORT_ONLY_BASE_ADRS);
j3 1:e1ee2549a047 257 local_data[cnt++] = data;
j3 0:350a850a7191 258
j3 0:350a850a7191 259 //no need for read, modify, write.
j3 0:350a850a7191 260 //Fx is intended to write whole register
j3 1:e1ee2549a047 261 result = _p_i2c->write(_w_adrs, local_data, cnt, false);
j3 1:e1ee2549a047 262
j3 1:e1ee2549a047 263 return result;
j3 1:e1ee2549a047 264 }
j3 1:e1ee2549a047 265
j3 1:e1ee2549a047 266
j3 1:e1ee2549a047 267 //*********************************************************************
j3 1:e1ee2549a047 268 int16_t Max7300::read_8_ports(max7300_port_number_t low_port)
j3 1:e1ee2549a047 269 {
j3 1:e1ee2549a047 270 int16_t result = -1;
j3 1:e1ee2549a047 271 char data[2];
j3 1:e1ee2549a047 272
j3 1:e1ee2549a047 273 if((low_port >= MAX7300_PORT_04) && (low_port <= MAX7300_PORT_24))
j3 1:e1ee2549a047 274 {
j3 1:e1ee2549a047 275 data[0] = low_port + MAX7300_8_PORTS_OFFSET;
j3 1:e1ee2549a047 276
j3 1:e1ee2549a047 277 //set internal register pointer to port data register
j3 1:e1ee2549a047 278 result = _p_i2c->write(_w_adrs, data, 1, true);
j3 1:e1ee2549a047 279 if(!result)
j3 1:e1ee2549a047 280 {
j3 1:e1ee2549a047 281 //get port data
j3 1:e1ee2549a047 282 result = _p_i2c->read(_w_adrs, (data + 1), 1, false);
j3 1:e1ee2549a047 283 if(!result)
j3 1:e1ee2549a047 284 {
j3 1:e1ee2549a047 285 result = data[1];
j3 1:e1ee2549a047 286 }
j3 1:e1ee2549a047 287 else
j3 1:e1ee2549a047 288 {
j3 1:e1ee2549a047 289 result = -1;
j3 1:e1ee2549a047 290 }
j3 1:e1ee2549a047 291 }
j3 1:e1ee2549a047 292 }
j3 1:e1ee2549a047 293
j3 1:e1ee2549a047 294 return result;
j3 1:e1ee2549a047 295 }
j3 1:e1ee2549a047 296
j3 1:e1ee2549a047 297
j3 1:e1ee2549a047 298 //*********************************************************************
j3 1:e1ee2549a047 299 int16_t Max7300::write_8_ports(max7300_port_number_t low_port, uint8_t data)
j3 1:e1ee2549a047 300 {
j3 1:e1ee2549a047 301 int16_t result = -1;
j3 1:e1ee2549a047 302 char local_data[2];
j3 1:e1ee2549a047 303 uint8_t cnt = 0;
j3 1:e1ee2549a047 304
j3 1:e1ee2549a047 305 if(low_port <= MAX7300_PORT_24)
j3 1:e1ee2549a047 306 {
j3 1:e1ee2549a047 307 local_data[cnt++] = low_port + MAX7300_8_PORTS_OFFSET;
j3 1:e1ee2549a047 308 local_data[cnt++] = data;
j3 1:e1ee2549a047 309
j3 1:e1ee2549a047 310 //no need for read, modify, write.
j3 1:e1ee2549a047 311 //Fx is intended to write whole register
j3 1:e1ee2549a047 312 result = _p_i2c->write(_w_adrs, local_data, cnt, false);
j3 1:e1ee2549a047 313 }
j3 0:350a850a7191 314
j3 0:350a850a7191 315 return result;
j3 0:350a850a7191 316 }
j3 0:350a850a7191 317
j3 0:350a850a7191 318
j3 0:350a850a7191 319 //*********************************************************************
j3 1:e1ee2549a047 320 int16_t Max7300::read_mask_register(bool enable_snapshot)
j3 0:350a850a7191 321 {
j3 0:350a850a7191 322 int16_t result = -1;
j3 0:350a850a7191 323 char data[2];
j3 0:350a850a7191 324
j3 1:e1ee2549a047 325 data[0] = MAX7300_TRANSITION_DETECT_MASK;
j3 0:350a850a7191 326
j3 1:e1ee2549a047 327 //set internal register pointer to mask register
j3 0:350a850a7191 328 result = _p_i2c->write(_w_adrs, data, 1, true);
j3 0:350a850a7191 329 if(!result)
j3 0:350a850a7191 330 {
j3 1:e1ee2549a047 331 //get mask data
j3 1:e1ee2549a047 332 result = _p_i2c->read(_w_adrs, (data + 1), 1, false);
j3 0:350a850a7191 333 if(!result)
j3 0:350a850a7191 334 {
j3 1:e1ee2549a047 335 if(enable_snapshot)
j3 1:e1ee2549a047 336 {
j3 1:e1ee2549a047 337 result = enable_transition_detection();
j3 1:e1ee2549a047 338 if(!result)
j3 1:e1ee2549a047 339 {
j3 1:e1ee2549a047 340 result = data[1];
j3 1:e1ee2549a047 341 }
j3 1:e1ee2549a047 342 else
j3 1:e1ee2549a047 343 {
j3 1:e1ee2549a047 344 result = -1;
j3 1:e1ee2549a047 345 }
j3 1:e1ee2549a047 346 }
j3 1:e1ee2549a047 347 else
j3 1:e1ee2549a047 348 {
j3 1:e1ee2549a047 349 result = data[1];
j3 1:e1ee2549a047 350 }
j3 0:350a850a7191 351 }
j3 0:350a850a7191 352 else
j3 0:350a850a7191 353 {
j3 0:350a850a7191 354 result = -1;
j3 0:350a850a7191 355 }
j3 0:350a850a7191 356 }
j3 1:e1ee2549a047 357
j3 1:e1ee2549a047 358 return result;
j3 1:e1ee2549a047 359 }
j3 1:e1ee2549a047 360
j3 1:e1ee2549a047 361
j3 1:e1ee2549a047 362 //*********************************************************************
j3 1:e1ee2549a047 363 int16_t Max7300::write_mask_register(uint8_t data)
j3 1:e1ee2549a047 364 {
j3 1:e1ee2549a047 365 int16_t result = -1;
j3 1:e1ee2549a047 366 char local_data[2];
j3 1:e1ee2549a047 367 uint8_t cnt = 0;
j3 1:e1ee2549a047 368
j3 1:e1ee2549a047 369 local_data[cnt++] = MAX7300_TRANSITION_DETECT_MASK;
j3 1:e1ee2549a047 370 local_data[cnt++] = data;
j3 1:e1ee2549a047 371
j3 1:e1ee2549a047 372 //no need for read, modify, write.
j3 1:e1ee2549a047 373 //Fx is intended to write whole register
j3 1:e1ee2549a047 374 result = _p_i2c->write(_w_adrs, local_data, cnt, false);
j3 1:e1ee2549a047 375
j3 0:350a850a7191 376 return result;
j3 0:350a850a7191 377 }
j3 0:350a850a7191 378
j3 0:350a850a7191 379
j3 0:350a850a7191 380 //*********************************************************************
j3 1:e1ee2549a047 381 int16_t Max7300::write_config_register(bool set_clear, uint8_t data)
j3 0:350a850a7191 382 {
j3 0:350a850a7191 383 int16_t result = -1;
j3 1:e1ee2549a047 384 char local_data[2];
j3 1:e1ee2549a047 385 uint8_t cnt = 0;
j3 1:e1ee2549a047 386
j3 1:e1ee2549a047 387 local_data[cnt++] = MAX7300_CONFIGURATION;
j3 0:350a850a7191 388
j3 1:e1ee2549a047 389 //set internal register pointer to configuration register
j3 1:e1ee2549a047 390 result = _p_i2c->write(_w_adrs, local_data, 1, true);
j3 1:e1ee2549a047 391 if(!result)
j3 1:e1ee2549a047 392 {
j3 1:e1ee2549a047 393 //get current configuration register
j3 1:e1ee2549a047 394 result = _p_i2c->read(_w_adrs, (local_data + 1), 1, true);
j3 1:e1ee2549a047 395
j3 1:e1ee2549a047 396 if(!result)
j3 1:e1ee2549a047 397 {
j3 1:e1ee2549a047 398 if(set_clear)
j3 1:e1ee2549a047 399 {
j3 1:e1ee2549a047 400 local_data[cnt++] |= data;
j3 1:e1ee2549a047 401 }
j3 1:e1ee2549a047 402 else
j3 1:e1ee2549a047 403 {
j3 1:e1ee2549a047 404 local_data[cnt++] &= ~data;
j3 1:e1ee2549a047 405 }
j3 1:e1ee2549a047 406
j3 1:e1ee2549a047 407 //write back to device
j3 1:e1ee2549a047 408 result = _p_i2c->write(_w_adrs, local_data, cnt, false);
j3 1:e1ee2549a047 409 }
j3 1:e1ee2549a047 410 }
j3 1:e1ee2549a047 411
j3 0:350a850a7191 412 return result;
j3 0:350a850a7191 413 }