Fork of 24LCxx_I2C. Works for Renesas EEPROMs. Fixes problems with PageWrites over page boundaries.

Fork of 24LCxx_I2C by Yann Garcia

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers 24LCxx_I2C.cpp Source File

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