Fork of 24LCxx_I2C. Works for Renesas EEPROMs. Fixes problems with PageWrites over page boundaries.
Fork of 24LCxx_I2C by
24LCxx_I2C.cpp
00001 /* mbed simplified access to Microchip 24LCxx Serial EEPROM devices (I2C) 00002 * Copyright (c) 2010-2012 ygarcia, MIT License 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00005 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00006 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00007 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00008 * furnished to do so, subject to the following conditions: 00009 * 00010 * The above copyright notice and this permission notice shall be included in all copies or 00011 * substantial portions of the Software. 00012 * 00013 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00014 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00015 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00016 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00017 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00018 */ 00019 #include <iostream> 00020 #include <sstream> 00021 00022 #include "24LCxx_I2C.h" 00023 00024 namespace _24LCXX_I2C 00025 { 00026 00027 unsigned char C24LCXX_I2C::I2CModuleRefCounter = 0; 00028 00029 C24LCXX_I2C::C24LCXX_I2C(const PinName p_sda, const PinName p_scl, const unsigned char p_address, const PinName p_wp, const unsigned int p_frequency, 00030 const uint32_t deviceSize, const uint8_t pageSize) : _internalId("") 00031 { 00032 DEBUG_ENTER("C24LCXX_I2C") 00033 00034 if (C24LCXX_I2C::I2CModuleRefCounter != 0) { 00035 error("C24LCXX_I2C: Wrong params"); 00036 } 00037 #ifdef __DEBUG 00038 std::ostringstream out(std::ostringstream::out); 00039 out << "C24LCXX_I2C #" << C24LCXX_I2C::I2CModuleRefCounter; 00040 _internalId.assign(out.str()); 00041 DEBUG("C24LCXX_I2C: _internalId='%s'", _internalId.c_str()) 00042 #endif // __DEBUG 00043 _i2cInstance = new I2C(p_sda, p_scl); //, "24LCxx_I2C"); 00044 C24LCXX_I2C::I2CModuleRefCounter += 1; 00045 DEBUG_ENTER("C24LCXX_I2C: refCounter=%d", C24LCXX_I2C::I2CModuleRefCounter) 00046 00047 _slaveAddress = (p_address << 1) | 0xa0; // Slave address format is: 1 0 1 0 A3 A2 A1 R/W 00048 DEBUG("C24LCXX_I2C: I2C slave adress: 0x%02x", _slaveAddress) 00049 _i2cInstance->frequency(p_frequency); // Set the frequency of the I2C interface 00050 if (p_wp != NC) { 00051 DEBUG("C24LCXX_I2C: WP managed"); 00052 _wp = new DigitalOut(p_wp); 00053 _wp->write(0); // Disable write protect 00054 } else { 00055 DEBUG("C24LCXX_I2C: WP not managed"); 00056 _wp = NULL; // Not used 00057 } 00058 00059 DEBUG("C24LCXX_I2C: Device-Size %i kbit", deviceSize); 00060 00061 DEBUG("C24LCXX_I2C: Page-Size %i Bytes", pageSize); 00062 00063 _pageSize = pageSize; //TODO Check for valid values 00064 _deviceSize = deviceSize; //TODO Check for valid values 00065 00066 DEBUG_LEAVE("C24LCXX_I2C") 00067 } 00068 00069 C24LCXX_I2C::~C24LCXX_I2C() 00070 { 00071 DEBUG_ENTER("~C24LCXX_I2C") 00072 00073 // Release I2C instance 00074 DEBUG_ENTER("~C24LCXX_I2C: refCounter=%d", C24LCXX_I2C::I2CModuleRefCounter) 00075 C24LCXX_I2C::I2CModuleRefCounter -= 1; 00076 if (C24LCXX_I2C::I2CModuleRefCounter == 0) { 00077 delete _i2cInstance; 00078 _i2cInstance = NULL; 00079 } 00080 // Release _wp if required 00081 if (_wp != NULL) { 00082 _wp->write(0); 00083 delete _wp; 00084 } 00085 00086 DEBUG_LEAVE("~C24LCXX_I2C") 00087 } 00088 00089 bool C24LCXX_I2C::WriteProtect(const bool p_writeProtect) 00090 { 00091 if (_wp != NULL) { 00092 DEBUG("WP set to: %x", (int)p_writeProtect) 00093 _wp->write((int)(p_writeProtect)); 00094 return true; 00095 } 00096 00097 return false; 00098 } 00099 00100 bool C24LCXX_I2C::EraseMemoryArea(const short p_startAddress, const int p_count, const unsigned char p_pattern) 00101 { 00102 DEBUG_ENTER("C24LCXX_I2C::EraseMemoryArea: 0x%02x - %d - 0x%02x", p_startAddress, p_count, p_pattern) 00103 00104 std::vector<unsigned char> eraseBuffer(p_count, p_pattern); 00105 return Write(p_startAddress, eraseBuffer, false); 00106 } 00107 00108 bool C24LCXX_I2C::Write(const short p_address, const unsigned char p_byte) 00109 { 00110 DEBUG_ENTER("C24LCXX_I2C::Write (byte): Memory address: 0x%02x - 0x%02x", p_address, p_byte) 00111 00112 // 1.Prepare buffer 00113 char i2cBuffer[3]; // Memory address + one byte of data 00114 // 1.1. Memory address 00115 //short address = p_address + 1; // Index start to 1 00116 short address = p_address; // no Index + 1 00117 i2cBuffer[0] = (unsigned char)(address >> 8); 00118 DEBUG("C24LCXX_I2C::Write (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00119 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff); 00120 DEBUG("C24LCXX_I2C::Write (byte): pI2CBuffer[1]: 0x%02x", i2cBuffer[1]) 00121 // 1.2. Datas 00122 i2cBuffer[2] = p_byte; 00123 DEBUG("C24LCXX_I2C::Write (byte): value=0x%02x", i2cBuffer[2]) 00124 00125 // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop 00126 int result = _i2cInstance->write(_slaveAddress, i2cBuffer, 3); 00127 wait(0.02); 00128 00129 DEBUG_LEAVE("C24LCXX_I2C::Write (byte) %x", (bool)(result == 0)) 00130 return (bool)(result == 0); 00131 } 00132 00133 bool C24LCXX_I2C::Write(const short p_address, const short p_short, const C24LCXX_I2C::Mode p_mode) 00134 { 00135 DEBUG_ENTER("C24LCXX_I2C::Write (short): Memory address:0x%02x, Mode:%d", p_address, p_mode) 00136 00137 // 1.Prepare buffer 00138 char i2cBuffer[4]; // Memory address + one short (2 bytes) 00139 // 1.1. Memory address 00140 //short address = p_address + 1; // Index start to 1 00141 short address = p_address; // no Index+1 00142 i2cBuffer[0] = (unsigned char)(address >> 8); 00143 DEBUG("C24LCXX_I2C::Write (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00144 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff); 00145 DEBUG("C24LCXX_I2C::Write (short): pI2CBuffer[1]: 0x%02x", i2cBuffer[1]) 00146 // 1.2. Datas 00147 if (p_mode == BigEndian) { 00148 i2cBuffer[2] = (unsigned char)(p_short >> 8); 00149 i2cBuffer[3] = (unsigned char)((unsigned char)p_short & 0xff); 00150 } else { 00151 i2cBuffer[2] = (unsigned char)((unsigned char)p_short & 0xff); 00152 i2cBuffer[3] = (unsigned char)(p_short >> 8); 00153 } 00154 DEBUG("C24LCXX_I2C::Write (short): value=0x%02x%02x", i2cBuffer[2], i2cBuffer[3]) 00155 00156 // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop 00157 int result = _i2cInstance->write(_slaveAddress, i2cBuffer, 4); 00158 wait(0.02); 00159 00160 DEBUG_LEAVE("C24LCXX_I2C::Write (short) %x", (bool)(result == 0)) 00161 return (bool)(result == 0); 00162 } 00163 00164 bool C24LCXX_I2C::Write(const short p_address, const int p_int, const C24LCXX_I2C::Mode p_mode) 00165 { 00166 DEBUG_ENTER("C24LCXX_I2C::Write (int): Memory address:0x%02x, Mode:%d", p_address, p_mode) 00167 00168 // 1.Prepare buffer 00169 char i2cBuffer[6]; // Memory address + one integer (4 bytes) 00170 // 1.1. Memory address 00171 //short address = p_address + 1; // Index start to 1 00172 short address = p_address; // no Index+1 00173 i2cBuffer[0] = (unsigned char)(address >> 8); 00174 DEBUG("C24LCXX_I2C::Write (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00175 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff); 00176 DEBUG("C24LCXX_I2C::Write (int): pI2CBuffer[1]: 0x%02x", i2cBuffer[1]) 00177 // 1.2. Datas 00178 if (p_mode == BigEndian) { 00179 i2cBuffer[2] = (unsigned char)(p_int >> 24); 00180 i2cBuffer[3] = (unsigned char)(p_int >> 16); 00181 i2cBuffer[4] = (unsigned char)(p_int >> 8); 00182 i2cBuffer[5] = (unsigned char)((unsigned char)p_int & 0xff); 00183 } else { 00184 i2cBuffer[2] = (unsigned char)((unsigned char)p_int & 0xff); 00185 i2cBuffer[3] = (unsigned char)(p_int >> 8); 00186 i2cBuffer[4] = (unsigned char)(p_int >> 16); 00187 i2cBuffer[5] = (unsigned char)(p_int >> 24); 00188 } 00189 DEBUG("C24LCXX_I2C::Write (int): value=0x%02x%02x%02x%02x", i2cBuffer[2], i2cBuffer[3], i2cBuffer[4], i2cBuffer[5]) 00190 00191 // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop 00192 int result = _i2cInstance->write(_slaveAddress, i2cBuffer, 6); 00193 wait(0.02); 00194 00195 DEBUG_LEAVE("C24LCXX_I2C::Write (int) %x", (bool)(result == 0)) 00196 return (bool)(result == 0); 00197 } 00198 00199 bool C24LCXX_I2C::Write(const short p_address, const std::string & p_string, const bool p_storeLength, const int p_length2write) 00200 { 00201 DEBUG_ENTER("C24LCXX_I2C::Write (std::string)") 00202 return Write(p_address, p_string.c_str(), p_storeLength, p_length2write); 00203 } 00204 00205 bool C24LCXX_I2C::Write(const short p_address, const std::vector<unsigned char> & p_datas, const bool p_storeLength, const int p_length2write) 00206 { 00207 DEBUG_ENTER("C24LCXX_I2C::Write (std::vector)") 00208 00209 int length = (p_length2write == -1) ? p_datas.size() : p_length2write; 00210 unsigned char array[length]; 00211 std::copy(p_datas.begin(), p_datas.end(), array); 00212 bool result = Write(p_address, array, p_storeLength, length); 00213 wait(0.02); 00214 00215 DEBUG_LEAVE("C24LCXX_I2C::Write (std::vector): %d", result) 00216 return result; 00217 } 00218 00219 bool C24LCXX_I2C::Write(const short p_address, const char * p_datas, const bool p_storeLength, const int p_length2write) 00220 { 00221 DEBUG_ENTER("C24LCXX_I2C::Write (char *): Memory address: 0x%02x - %x - %d", p_address, p_storeLength, p_length2write) 00222 00223 // 1.Prepare buffer 00224 int length = (p_length2write == -1) ? strlen(p_datas) : p_length2write; 00225 if (p_storeLength) { 00226 length += 4; // Add four bytes for the length as integer 00227 } 00228 DEBUG("C24LCXX_I2C::Write (char *): length:%d", length) 00229 00230 char i2cBuffer[2 + length]; 00231 // 1.1. Memory address 00232 //short address = p_address + 1; // Index start to 1 00233 short address = p_address; // no Index+1 00234 // i2cBuffer[0] = (unsigned char)(address >> 8); 00235 // DEBUG("C24LCXX_I2C::Write (char *): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00236 // i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff); 00237 // DEBUG("C24LCXX_I2C::Write (char *): pI2CBuffer[1]: 0x%02x", i2cBuffer[1]) 00238 // 1.2. Datas 00239 if (p_storeLength) { 00240 // Fill the length 00241 i2cBuffer[2] = (unsigned char)(length >> 24); 00242 i2cBuffer[3] = (unsigned char)(length >> 16); 00243 i2cBuffer[4] = (unsigned char)(length >> 8); 00244 i2cBuffer[5] = (unsigned char)((unsigned char)length & 0xff); 00245 for (int i = 0; i < length - 4; i++) { 00246 i2cBuffer[6 + i] = *(p_datas + i); 00247 } 00248 } else { // The length was not stored 00249 for (int i = 0; i < length; i++) { 00250 i2cBuffer[2 + i] = *(p_datas + i); 00251 } 00252 } 00253 00254 //HEXADUMP((unsigned char *) i2cBuffer+2, length); 00255 00256 /* 00257 // 2. Send I2C start + Memory Address 00258 _i2cInstance->write(_slaveAddress, i2cBuffer, 2, true); 00259 wait(0.02); 00260 00261 // 3. Send Datas + I2C stop 00262 int result = _i2cInstance->write(_slaveAddress, i2cBuffer+2, length); 00263 wait(0.02); 00264 */ 00265 //write pages to EEPROM 00266 int result = i2cWrite(address,i2cBuffer+2, length); 00267 wait(0.02); 00268 00269 DEBUG_LEAVE("C24LCXX_I2C::Write (char *) %x", (bool)(result == 0)) 00270 return (bool)(result == 0); 00271 } 00272 00273 bool C24LCXX_I2C::Write(const short p_address, const unsigned char *p_datas, const bool p_storeLength, const int p_length2write) 00274 { 00275 DEBUG_ENTER("C24LCXX_I2C::Write (byte *): Memory address: 0x%02x - %x - %d", p_address, p_storeLength, p_length2write) 00276 return Write(p_address, (const char *)p_datas, p_storeLength, p_length2write); 00277 } 00278 00279 00280 int C24LCXX_I2C::i2cWrite(short address, const char *data, int length) 00281 { 00282 //write to EEPROM in chunks of pagesize 00283 int rv = 0; 00284 while (length > 0) { 00285 int bytesUntilPageBoundary = _pageSize - address % _pageSize; 00286 int cnt = min(length, bytesUntilPageBoundary); 00287 char i2cBuffer[2 + _pageSize]; 00288 // 1.1. Memory address 00289 00290 i2cBuffer[0] = (unsigned char)(address >> 8); 00291 DEBUG("C24LCXX_I2C::i2cWrite (char *): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00292 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff); 00293 DEBUG("C24LCXX_I2C::i2cWrite (char *): pI2CBuffer[1]: 0x%02x", i2cBuffer[1]) 00294 DEBUG("C24LCXX_I2C::i2cWrite (char *): length : %i", cnt) 00295 00296 //Copy data after address 00297 for (int i = 0; i < cnt; i++) { 00298 i2cBuffer[2 + i] = *(data + i); 00299 } 00300 00301 //HEXADUMP((unsigned char *) i2cBuffer, cnt+2); 00302 // Write data; max until page boundary 00303 int rv = _i2cInstance->write(_slaveAddress, i2cBuffer, cnt+2); 00304 00305 if (rv != 0) return rv; 00306 00307 address += cnt; 00308 data += cnt; 00309 length -= cnt; 00310 } 00311 return rv; 00312 } 00313 00314 00315 bool C24LCXX_I2C::Read(const short p_address, unsigned char * p_byte) 00316 { 00317 DEBUG_ENTER("C24LCXX_I2C::Read (byte): Memory address:0x%02x", p_address) 00318 00319 // 1.Prepare buffer 00320 char i2cBuffer[2]; 00321 // 1.1. Memory address 00322 i2cBuffer[0] = (unsigned char)(p_address >> 8); 00323 DEBUG("C24LCXX_I2C::Read (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00324 i2cBuffer[1] = (unsigned char)((unsigned char)p_address & 0xff); 00325 DEBUG("C24LCXX_I2C::Read (byte): pI2CBuffer[1]: 0x%02x", i2cBuffer[1]) 00326 00327 // 2. Send I2C start + memory address 00328 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) { 00329 wait(0.02); 00330 DEBUG("C24LCXX_I2C::Read (byte): Write memory done") 00331 // 2. Read data + I2C stop 00332 int result = _i2cInstance->read(_slaveAddress, (char *)p_byte, 1); 00333 wait(0.02); 00334 00335 DEBUG_LEAVE("C24LCXX_I2C::Read (byte): %x", (bool)(result == 0)) 00336 return (bool)(result == 0); 00337 } 00338 00339 DEBUG_LEAVE("C24LCXX_I2C::Read (byte) (false)") 00340 return false; 00341 } 00342 00343 bool C24LCXX_I2C::Read(const short p_address, short *p_short, const C24LCXX_I2C::Mode p_mode) 00344 { 00345 DEBUG_ENTER("C24LCXX_I2C::Read (short): Memory address:0x%02x, Mode:%d", p_address, p_mode) 00346 00347 // 1.Prepare buffer 00348 char i2cBuffer[2]; 00349 // 1.1. Memory address 00350 i2cBuffer[0] = (unsigned char)(p_address >> 8); 00351 DEBUG("C24LCXX_I2C::Read (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00352 i2cBuffer[1] = (unsigned char)((unsigned char)p_address & 0xff); 00353 DEBUG("C24LCXX_I2C::Read (short): pI2CBuffer[1]: 0x%02x", i2cBuffer[1]) 00354 00355 // 2. Send I2C start + memory address 00356 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) { 00357 wait(0.02); 00358 DEBUG("C24LCXX_I2C::Read (short): Write memory done") 00359 // 2. Read data + I2C stop 00360 int result = _i2cInstance->read(_slaveAddress, i2cBuffer, 2); 00361 if (result == 0) { 00362 DEBUG("C24LCXX_I2C::Read (short): value: 0x%02x - 0x%02x", i2cBuffer[0], i2cBuffer[1]) 00363 if (p_mode == BigEndian) { 00364 *p_short = (short)(i2cBuffer[0] << 8 | i2cBuffer[1]); 00365 } else { 00366 *p_short = (short)(i2cBuffer[1] << 8 | i2cBuffer[0]); 00367 } 00368 00369 DEBUG_LEAVE("C24LCXX_I2C::Read (short): 0x%04x", *p_short) 00370 return true; 00371 } 00372 } 00373 00374 DEBUG_LEAVE("C24LCXX_I2C::Read (short) (false)") 00375 return false; 00376 } 00377 00378 bool C24LCXX_I2C::Read(const short p_address, int *p_int, const C24LCXX_I2C::Mode p_mode) 00379 { 00380 DEBUG_ENTER("C24LCXX_I2C::Read (int): Memory address:0x%02x, Mode:%d", p_address, p_mode) 00381 00382 // 1.Prepare buffer 00383 char i2cBuffer[4]; 00384 // 1.1. Memory address 00385 i2cBuffer[0] = (unsigned char)(p_address >> 8); 00386 DEBUG("C24LCXX_I2C::Read (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00387 i2cBuffer[1] = (unsigned char)((unsigned char)p_address & 0xff); 00388 DEBUG("C24LCXX_I2C::Read (int): pI2CBuffer[1]: 0x%02x", i2cBuffer[1]) 00389 00390 // 2. Send I2C start + memory address 00391 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) { 00392 wait(0.02); 00393 DEBUG("C24LCXX_I2C::Read (int): Write memory done") 00394 // 2. Read data + I2C stop 00395 int result = _i2cInstance->read(_slaveAddress, i2cBuffer, 4); 00396 if (result == 0) { 00397 DEBUG("C24LCXX_I2C::Read (int): value: 0x%02x - 0x%02x - 0x%02x - 0x%02x", i2cBuffer[0], i2cBuffer[1], i2cBuffer[2], i2cBuffer[3]) 00398 wait(0.02); 00399 if (p_mode == BigEndian) { 00400 *p_int = (int)(i2cBuffer[0] << 24 | i2cBuffer[1] << 16 | i2cBuffer[2] << 8 | i2cBuffer[3]); 00401 } else { 00402 *p_int = (int)(i2cBuffer[3] << 24 | i2cBuffer[2] << 16 | i2cBuffer[1] << 8 | i2cBuffer[0]); 00403 } 00404 00405 DEBUG_LEAVE("C24LCXX_I2C::Read (int): %d", *p_int) 00406 return true; 00407 } 00408 00409 DEBUG_LEAVE("C24LCXX_I2C::Read (int):false") 00410 return false; 00411 } 00412 00413 DEBUG_LEAVE("C24LCXX_I2C::Read (int) (false)") 00414 return false; 00415 } 00416 00417 bool C24LCXX_I2C::Read(const short p_address, std::vector<unsigned char> & p_datas, const bool p_readLengthFirst, const int p_length2write) 00418 { 00419 DEBUG_ENTER("C24LCXX_I2C::Read (vector): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write) 00420 00421 // 1.Prepare buffer 00422 short address = p_address; 00423 int length = 0; 00424 if (p_readLengthFirst) { 00425 if (!Read(address, &length)) { // Read the length in big endian mode 00426 DEBUG_LEAVE("C24LCXX_I2C::Read (vector) Failed to read length") 00427 return false; 00428 } 00429 DEBUG("C24LCXX_I2C::Read (vector): length= %d", length) 00430 if (length == 0) { 00431 return true; 00432 } 00433 address += 4; // Skip the length value 00434 length -= 4; // length is the size of (string length + string) 00435 } else { 00436 if (p_length2write == -1) { 00437 length = p_datas.size(); 00438 } else { 00439 length = p_length2write; 00440 } 00441 } 00442 DEBUG("C24LCXX_I2C::Read (vector): length= %d", length) 00443 00444 // 2. Memory address 00445 char i2cBuffer[2]; 00446 i2cBuffer[0] = (unsigned char)(address >> 8); 00447 DEBUG("C24LCXX_I2C::Read (vector): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00448 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff); 00449 DEBUG("C24LCXX_I2C::Read (vector): pI2CBuffer[1]: 0x%02x", i2cBuffer[1]) 00450 00451 // 3. Send I2C start + memory address 00452 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) { 00453 wait(0.02); 00454 DEBUG("C24LCXX_I2C::Read (vector): Write memory done") 00455 // 4. read data + I2C stop 00456 unsigned char buffer[length]; 00457 int result = _i2cInstance->read(_slaveAddress, (char *)buffer, length); 00458 wait(0.02); 00459 if (result == 0) { 00460 p_datas.assign(buffer, buffer + length); 00461 00462 DEBUG_LEAVE("C24LCXX_I2C::Read (vector): %x", (bool)(result == 0)) 00463 return (bool)(result == 0); 00464 } 00465 } 00466 00467 DEBUG_LEAVE("C24LCXX_I2C::Read (vector) (false)") 00468 return false; 00469 } 00470 00471 bool C24LCXX_I2C::Read(const short p_address, std::string & p_string, const bool p_readLengthFirst, const int p_length2write) 00472 { 00473 DEBUG_ENTER("C24LCXX_I2C::Read (string): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write) 00474 00475 /* std::vector<unsigned char> datas; 00476 if (Read(p_address, datas, p_readLengthFirst, p_length2write) == true) { 00477 p_string.assign((char *)datas.begin(), datas.size()); 00478 00479 return true; 00480 } 00481 00482 DEBUG_LEAVE("C24LCXX_I2C::Read (string) (false)") 00483 return false; 00484 */ 00485 00486 // 1.Prepare buffer 00487 short address = p_address; 00488 int length = -1; 00489 if (p_readLengthFirst) { // The string was stored with its length 00490 if (!Read(address, &length)) { // Read the length as integer in big endian mode 00491 DEBUG_ERROR("C24LCXX_I2C::Read (string): Failed to read length") 00492 return false; 00493 } 00494 wait(0.02); 00495 DEBUG("C24LCXX_I2C::Read (string): length=%d", length) 00496 if (length == 0) { 00497 DEBUG_ERROR("C24LCXX_I2C::Read (string): empty") 00498 return true; 00499 } 00500 address += 4; // Skip the length value size 00501 length -= 4; // length is the size of (string length + string) 00502 } else { // The string length is provided by p_length2write parameter 00503 if (p_length2write == -1) { 00504 length = p_string.size(); 00505 } else { 00506 length = p_length2write; 00507 p_string.resize(p_length2write); 00508 } 00509 } 00510 DEBUG("C24LCXX_I2C::Read (string): Address=0x%02x - Length=%d", address, length) 00511 00512 // 2. Memory address 00513 char i2cBuffer[2]; 00514 i2cBuffer[0] = (unsigned char)(address >> 8); 00515 DEBUG("C24LCXX_I2C::Read (string): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00516 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff); 00517 DEBUG("C24LCXX_I2C::Read (string): pI2CBuffer[1]: 0x%02x", i2cBuffer[1]) 00518 00519 // 3. Send I2C start + memory address with repeat start 00520 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) { 00521 wait(0.02); 00522 DEBUG("C24LCXX_I2C::Read (string): Write memory done") 00523 // 4. Read data + I2C stop 00524 char buffer[length]; 00525 int result = _i2cInstance->read(_slaveAddress, (char *)buffer, length); 00526 if (result == 0) { 00527 p_string.assign(buffer, length); 00528 00529 return true; 00530 } 00531 } 00532 00533 DEBUG_LEAVE("C24LCXX_I2C::Read (string) (false)") 00534 return false; 00535 } 00536 00537 bool C24LCXX_I2C::Read(const short p_address, unsigned char * p_datas, bool p_readLengthFirst , int p_length2write) 00538 { 00539 DEBUG_ENTER("C24LCXX_I2C::Read (char *): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write) 00540 00541 // 1.Prepare buffer 00542 short address = p_address; 00543 int length = -1; 00544 if (p_readLengthFirst) { // The string was stored with its length 00545 if (!Read(address, &length)) { // Read the length as integer in big endian mode 00546 DEBUG_ERROR("C24LCXX_I2C::Read (char *): Failed to read length") 00547 return false; 00548 } 00549 wait(0.02); 00550 DEBUG("C24LCXX_I2C::Read (char *): length=%d", length) 00551 if (length == 0) { 00552 DEBUG_ERROR("C24LCXX_I2C::Read (char *): empty") 00553 return true; 00554 } 00555 address += 4; // Skip the length value size 00556 length -= 4; // length is the size of (string length + string) 00557 } else { // The string length is provided by p_length2write parameter 00558 if (p_length2write == -1) { 00559 // read the size of buffer 00560 length = strlen((const char*)p_datas); 00561 } else { 00562 length = p_length2write; 00563 } 00564 } 00565 DEBUG("C24LCXX_I2C::Read (char *): Address=0x%02x - Length=%d", address, length) 00566 00567 // 2. Memory address 00568 char i2cBuffer[2]; 00569 i2cBuffer[0] = (unsigned char)(address >> 8); 00570 DEBUG("C24LCXX_I2C::Read (char *): pI2CBuffer[0]: 0x%02x", i2cBuffer[0]) 00571 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff); 00572 DEBUG("C24LCXX_I2C::Read (char *): pI2CBuffer[1]: 0x%02x", i2cBuffer[1]) 00573 00574 // 3. Send I2C start + memory address with repeat start 00575 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) { 00576 wait(0.02); 00577 DEBUG("C24LCXX_I2C::Read (char *): Write memory done") 00578 // 4. Read data + I2C stop 00579 int result = _i2cInstance->read(_slaveAddress, (char *)p_datas, length); 00580 00581 HEXADUMP((unsigned char *) p_datas, length); 00582 00583 if (result == 0) { 00584 return true; 00585 } 00586 } 00587 00588 DEBUG_LEAVE("C24LCXX_I2C::Read (char *) (false)") 00589 return false; 00590 } 00591 00592 00593 #if defined(__DEBUG) 00594 void C24LCXX_I2C::DumpMemoryArea(const int p_address, const int p_count) 00595 { 00596 DEBUG_ENTER("C24LCXX_I2C::DumpMemoryArea: %d - %d", p_address, p_count) 00597 00598 DEBUG("C24LCXX_I2C::DumpMemoryArea: Reading datas..."); 00599 std::vector<unsigned char> datas(p_count); 00600 if (!Read(p_address, datas, false)) { // Read bytes, including the lenght indication, buffer size is not set before the call 00601 std::cout << "C24LCXX_I2C::DumpMemoryArea: read failed\r" << std::endl; 00602 } else { 00603 std::cout << "C24LCXX_I2C::DumpMemoryArea: Read bytes:\r" << std::endl; 00604 HEXADUMP(&datas[0], p_count); 00605 std::cout << "\r" << std::endl; 00606 } 00607 } 00608 #endif // _DEBUG 00609 00610 } // End of namespace _24LCXX_I2C
Generated on Sat Jul 30 2022 16:18:10 by
1.7.2
