Yann Garcia / FM24Vxx_I2C

Dependents:   FM24Vxx_I2CApp

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FM24Vxx_I2C.cpp Source File

FM24Vxx_I2C.cpp

00001 /* mbed simplified access to RAMTRON FV24xx Serial 3V F-RAM Memory (I2C)
00002  * Copyright (c) 20103 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 "FM24Vxx_I2C.h"
00023 
00024 namespace _FM24VXX_I2C {
00025 
00026     unsigned char CFM24VXX_I2C::I2CModuleRefCounter = 0;
00027 
00028     CFM24VXX_I2C::CFM24VXX_I2C(const PinName p_sda, const PinName p_scl, const unsigned char p_address, const PinName p_wp, const unsigned int p_frequency) : _internalId("") {
00029         DEBUG_ENTER("CFM24VXX_I2C")
00030 
00031         if (CFM24VXX_I2C::I2CModuleRefCounter != 0) {
00032             error("CFM24VXX_I2C: Wrong params");
00033         }
00034 #ifdef __DEBUG
00035         std::ostringstream out(std::ostringstream::out);
00036         out << "CFM24VXX_I2C #" << CFM24VXX_I2C::I2CModuleRefCounter;
00037         _internalId.assign(out.str());
00038         DEBUG("CFM24VXX_I2C: _internalId='%s'", _internalId.c_str())
00039 #endif // __DEBUG
00040         _i2cInstance = new I2C(p_sda, p_scl);
00041         CFM24VXX_I2C::I2CModuleRefCounter += 1;
00042         DEBUG_ENTER("CFM24VXX_I2C: refCounter=%d", CFM24VXX_I2C::I2CModuleRefCounter)
00043         // Memory page select is set to 0
00044         _slaveAddress = (p_address << 2) | 0xa0; // Slave address format is: 1 0 1 0 A2 A1 PS R/W, PS set to 0
00045         DEBUG("CFM24VXX_I2C: I2C slave adress:  0x%02x", _slaveAddress)
00046         _i2cInstance->frequency(p_frequency); // Set the frequency of the I2C interface
00047 
00048         if (p_wp != NC) {
00049             DEBUG("CFM24VXX_I2C: WP managed");
00050             _wp = new DigitalOut(p_wp);
00051             _wp->write(0); // Disable write protect
00052         } else {
00053             DEBUG("CFM24VXX_I2C: WP not managed");
00054             _wp = NULL; // Not used
00055         }
00056  
00057         // Retrieve device identifiers
00058         _deviceID = NULL;
00059         GetDevideIDs();
00060         
00061         _sn = NULL;
00062         GetSerialNumbers();
00063     
00064         DEBUG_LEAVE("CFM24VXX_I2C")
00065     }
00066 
00067     CFM24VXX_I2C::~CFM24VXX_I2C() {
00068         DEBUG_ENTER("~CFM24VXX_I2C")
00069     
00070         // Release I2C instance
00071         DEBUG_ENTER("~CFM24VXX_I2C: refCounter=%d", CFM24VXX_I2C::I2CModuleRefCounter)
00072         CFM24VXX_I2C::I2CModuleRefCounter -= 1;
00073         if (CFM24VXX_I2C::I2CModuleRefCounter == 0) {
00074             delete _i2cInstance;
00075             _i2cInstance = NULL;
00076             if (_deviceID != NULL) {
00077                 delete _deviceID;
00078                 _deviceID = NULL;
00079             }
00080         }
00081         // Release _wp if required
00082         if (_wp != NULL) {
00083             _wp->write(0);
00084             delete _wp;
00085         }
00086     
00087         DEBUG_LEAVE("~CFM24VXX_I2C")
00088     }
00089     
00090     bool CFM24VXX_I2C::WriteProtect(const bool p_writeProtect) {
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 CFM24VXX_I2C::GetDevideIDs() {
00101          DEBUG_ENTER("CFM24VXX_I2C::GetDevideIDs")
00102     
00103         // 1. Memory address
00104         char i2cBuffer[1];
00105         i2cBuffer[0] = (unsigned char)(_slaveAddress & 0xfc); //FIXME Change 0xfc into a const SET_PAGE_SELECT_0
00106         DEBUG("CFM24VXX_I2C::GetDevideIDs: pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
00107         // 2. Send I2C start + 0xF8 + I2C ReStart
00108        if (_i2cInstance->write(0xf8, i2cBuffer, 1, true) == 0) {
00109             //wait(0.02);
00110             DEBUG("CFM24VXX_I2C::GetDevideIDs: Write F8 done")
00111             // 3. read data + I2C stop
00112             unsigned char buffer[3];
00113             int result = _i2cInstance->read(0xf9, (char *)buffer, 3);
00114             //wait(0.02);
00115             if (result == 0) {
00116                 // 4. Setup the device IDs
00117                 _deviceID = new CFM24VXX_IDs(buffer[0], buffer[1], buffer[2]);
00118                 DEBUG("CFM24VXX_I2C::GetDevideIDs: %02x - %02x - %02x", buffer[0], buffer[1], buffer[2])
00119    
00120                 DEBUG_LEAVE("CFM24VXX_I2C::GetDevideIDs: %x", (bool)(result == 0))
00121                 return (bool)(result == 0);
00122             }
00123         }
00124     
00125         _deviceID = new CFM24VXX_IDs(0xff, 0xff, 0xff);
00126         DEBUG_LEAVE("CFM24VXX_I2C::GetDevideIDs (false)")
00127         return false;
00128     }
00129 
00130     bool CFM24VXX_I2C::GetSerialNumbers() {
00131         DEBUG_ENTER("CFM24VXX_I2C::GetSerialNumber")
00132         // 1. Memory address
00133         char i2cBuffer[1];
00134         i2cBuffer[0] = (unsigned char)(_slaveAddress & 0xfc); //FIXME Change 0xfc into a const SET_PAGE_SELECT_0
00135         DEBUG("CFM24VXX_I2C::GetSerialNumber: pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
00136         // 2. Send I2C start + 0xF8 + I2C ReStart
00137        if (_i2cInstance->write(0xf8, i2cBuffer, 1, true) == 0) {
00138             //wait(0.02);
00139             DEBUG("CFM24VXX_I2C::GetSerialNumber: Write F8 done")
00140             // 3. read data + I2C stop
00141             unsigned char buffer[8]; // See FM24V10_ds.pdf Page 10/16 Figure 15. 8-Byte Serial Number (read-only)
00142             int result = _i2cInstance->read(0xcd, (char *)buffer, 8);
00143             //wait(0.02);
00144             if (result == 0) {
00145                 // 4. Check if it is supported
00146                 if (buffer[7] != 0x00) { // SN supported
00147                     // 5. Compute CRC
00148                     unsigned char crc = ChecksumSN(buffer);
00149                     // 6. Check CRCs
00150                     if (buffer[7] == crc) {
00151                         _sn = new CFM24VXX_SN(buffer);
00152                         DEBUG_LEAVE("CFM24VXX_I2C::GetSerialNumber: true")
00153                         return true;
00154                      } else { // SN supported
00155                         DEBUG_LEAVE("CFM24VXX_I2C::GetSerialNumber: Checksum mismatch")
00156                         return false;
00157                      }
00158                } else { // SN supported
00159                     DEBUG_LEAVE("CFM24VXX_I2C::GetSerialNumber: Serial number not supported")
00160                     return true;
00161                 }
00162             }
00163         }
00164     
00165         DEBUG_LEAVE("CFM24VXX_I2C::GetSerialNumber (false)")
00166         return false;
00167     }
00168     
00169     bool CFM24VXX_I2C::EraseMemoryArea(const short p_startAddress, const int p_count, const unsigned char p_pattern) {
00170         DEBUG_ENTER("CFM24VXX_I2C::EraseMemoryArea: 0x%02x - %d - 0x%02x", p_startAddress, p_count, p_pattern)
00171     
00172         std::vector<unsigned char> eraseBuffer(p_count, p_pattern);
00173         return Write(p_startAddress, eraseBuffer, false);
00174     }
00175 
00176     bool CFM24VXX_I2C::Write(const short p_address, const unsigned char p_byte) {
00177         DEBUG_ENTER("CFM24VXX_I2C::Write (byte): Memory address: 0x%02x - 0x%02x", p_address, p_byte)
00178     
00179         // 1.Prepare buffer
00180         char i2cBuffer[3]; // Memory address + one byte of data
00181         // 1.1. Memory address
00182         short address = p_address + 1; // Index start to 1
00183         i2cBuffer[0] = (unsigned char)(address >> 8);
00184         DEBUG("CFM24VXX_I2C::Write (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
00185         i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
00186         DEBUG("CFM24VXX_I2C::Write (byte): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
00187         // 1.2. Datas
00188         i2cBuffer[2] = p_byte;
00189         DEBUG("CFM24VXX_I2C::Write (byte): value=0x%02x", i2cBuffer[2])
00190     
00191         // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
00192         int result = _i2cInstance->write(_slaveAddress, i2cBuffer, 3);
00193         //wait(0.02);
00194     
00195         DEBUG_LEAVE("CFM24VXX_I2C::Write (byte) %x", (bool)(result == 0))
00196         return (bool)(result == 0);
00197     }
00198     
00199     bool CFM24VXX_I2C::Write(const short p_address, const short p_short, const CFM24VXX_I2C::Mode p_mode) {
00200         DEBUG_ENTER("CFM24VXX_I2C::Write (short): Memory address:0x%02x, Mode:%d", p_address, p_mode)
00201     
00202         // 1.Prepare buffer
00203         char i2cBuffer[4]; // Memory address + one short (2 bytes)
00204         // 1.1. Memory address
00205         short address = p_address + 1; // Index start to 1
00206         i2cBuffer[0] = (unsigned char)(address >> 8);
00207         DEBUG("CFM24VXX_I2C::Write (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
00208         i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
00209         DEBUG("CFM24VXX_I2C::Write (short): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
00210         // 1.2. Datas
00211         if (p_mode == BigEndian) {
00212             i2cBuffer[2] = (unsigned char)(p_short >> 8);
00213             i2cBuffer[3] = (unsigned char)((unsigned char)p_short & 0xff);
00214         } else {
00215             i2cBuffer[2] = (unsigned char)((unsigned char)p_short & 0xff);
00216             i2cBuffer[3] = (unsigned char)(p_short >> 8);
00217         }
00218         DEBUG("CFM24VXX_I2C::Write (short): value=0x%02x%02x", i2cBuffer[2], i2cBuffer[3])
00219     
00220         // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
00221         int result = _i2cInstance->write(_slaveAddress, i2cBuffer, 4);
00222         //wait(0.02);
00223     
00224         DEBUG_LEAVE("CFM24VXX_I2C::Write (short) %x", (bool)(result == 0))
00225         return (bool)(result == 0);
00226     }
00227     
00228     bool CFM24VXX_I2C::Write(const short p_address, const int p_int, const CFM24VXX_I2C::Mode p_mode) {
00229         DEBUG_ENTER("CFM24VXX_I2C::Write (int): Memory address:0x%02x, Mode:%d", p_address, p_mode)
00230     
00231         // 1.Prepare buffer
00232         char i2cBuffer[6]; // Memory address + one integer (4 bytes)
00233         // 1.1. Memory address
00234         short address = p_address + 1; // Index start to 1
00235         i2cBuffer[0] = (unsigned char)(address >> 8);
00236         DEBUG("CFM24VXX_I2C::Write (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
00237         i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
00238         DEBUG("CFM24VXX_I2C::Write (int): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
00239         // 1.2. Datas
00240         if (p_mode == BigEndian) {
00241             i2cBuffer[2] = (unsigned char)(p_int >> 24);
00242             i2cBuffer[3] = (unsigned char)(p_int >> 16);
00243             i2cBuffer[4] = (unsigned char)(p_int >> 8);
00244             i2cBuffer[5] = (unsigned char)((unsigned char)p_int & 0xff);
00245         } else {
00246             i2cBuffer[2] = (unsigned char)((unsigned char)p_int & 0xff);
00247             i2cBuffer[3] = (unsigned char)(p_int >> 8);
00248             i2cBuffer[4] = (unsigned char)(p_int >> 16);
00249             i2cBuffer[5] = (unsigned char)(p_int >> 24);
00250         }
00251         DEBUG("CFM24VXX_I2C::Write (int): value=0x%02x%02x%02x%02x", i2cBuffer[2], i2cBuffer[3], i2cBuffer[4], i2cBuffer[5])
00252     
00253         // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
00254         int result = _i2cInstance->write(_slaveAddress, i2cBuffer, 6);
00255         //wait(0.02);
00256     
00257         DEBUG_LEAVE("CFM24VXX_I2C::Write (int) %x", (bool)(result == 0))
00258         return (bool)(result == 0);
00259     }
00260     
00261     bool CFM24VXX_I2C::Write(const short p_address, const std::string & p_string, const bool p_storeLength, const int p_length2write) {
00262         DEBUG_ENTER("CFM24VXX_I2C::Write (std::string)")
00263         return Write(p_address, p_string.c_str(), p_storeLength, p_length2write);
00264     }
00265     
00266     bool CFM24VXX_I2C::Write(const short p_address, const std::vector<unsigned char> & p_datas, const bool p_storeLength, const int p_length2write) {
00267         DEBUG_ENTER("CFM24VXX_I2C::Write (std::vector)")
00268     
00269         int length = (p_length2write == -1) ? p_datas.size() : p_length2write;
00270         unsigned char array[length];
00271         std::copy(p_datas.begin(), p_datas.end(), array);
00272         bool result = Write(p_address, array, p_storeLength, length);
00273         //wait(0.02);
00274     
00275         DEBUG_LEAVE("CFM24VXX_I2C::Write (std::vector): %d", result)
00276         return result;
00277     }
00278     
00279     bool CFM24VXX_I2C::Write(const short p_address, const char *p_string, const bool p_storeLength, const int p_length2write) {
00280         DEBUG_ENTER("CFM24VXX_I2C::Write (char *): Memory address: 0x%02x - %x - %d", p_address, p_storeLength, p_length2write)
00281     
00282         DEBUG("CFM24VXX_I2C::Write (char *): Slave address: %02x", _slaveAddress)
00283         // 1.Prepare buffer
00284         int length = (p_length2write == -1) ? strlen(p_string) : p_length2write;
00285         if (p_storeLength) {
00286             length += 4; // Add four bytes for the length as integer
00287         }
00288         DEBUG("CFM24VXX_I2C::Write (char *): length:%d", length)
00289         
00290         char i2cBuffer[2 + length];
00291         // 1.1. Memory address
00292         short address = p_address + 1;
00293         i2cBuffer[0] = (unsigned char)(address >> 8);
00294         DEBUG("CFM24VXX_I2C::Write (char *): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
00295         i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
00296         DEBUG("CFM24VXX_I2C::Write (char *): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
00297         // 1.2. Datas
00298         if (p_storeLength) {
00299             // Fill the length
00300             i2cBuffer[2] = (unsigned char)(length >> 24);
00301             i2cBuffer[3] = (unsigned char)(length >> 16);
00302             i2cBuffer[4] = (unsigned char)(length >> 8);
00303             i2cBuffer[5] = (unsigned char)((unsigned char)length & 0xff);
00304             for (int i = 0; i < length - 4; i++) {
00305                 i2cBuffer[6 + i] = *(p_string + i);
00306             }
00307         } else { // The length was not stored
00308             for (int i = 0; i < length; i++) {
00309                 i2cBuffer[2 + i] = *(p_string + i);
00310             }
00311         }
00312         
00313         // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
00314         int result = _i2cInstance->write(_slaveAddress, i2cBuffer, 2 + length);
00315         //wait(0.02);
00316     
00317         DEBUG_LEAVE("CFM24VXX_I2C::Write (char *) %x", (bool)(result == 0))
00318         return (bool)(result == 0);
00319     }
00320     
00321     bool CFM24VXX_I2C::Write(const short p_address, const unsigned char *p_datas, const bool p_storeLength, const int p_length2write) {
00322         DEBUG_ENTER("CFM24VXX_I2C::Write (byte *): Memory address: 0x%02x - %x - %d", p_address, p_storeLength, p_length2write)
00323         return Write(p_address, (const char *)p_datas, p_storeLength, p_length2write);
00324     }
00325     
00326     bool CFM24VXX_I2C::Read(const short p_address, unsigned char * p_byte) {
00327         DEBUG_ENTER("CFM24VXX_I2C::Read (byte): Memory address:0x%02x", p_address)
00328     
00329         // 1.Prepare buffer
00330         char i2cBuffer[2];
00331         // 1.1. Memory address
00332         i2cBuffer[0] = (unsigned char)(p_address >> 8);
00333         DEBUG("CFM24VXX_I2C::Read (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
00334         i2cBuffer[1] = (unsigned char)((unsigned char)p_address & 0xff);
00335         DEBUG("CFM24VXX_I2C::Read (byte): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
00336     
00337         // 2. Send I2C start + memory address
00338         if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) {
00339             //wait(0.02);
00340             DEBUG("CFM24VXX_I2C::Read (byte): Write memory done")
00341             // 2. Read data + I2C stop
00342             int result = _i2cInstance->read(_slaveAddress, (char *)p_byte, 1);
00343             //wait(0.02);
00344     
00345             DEBUG_LEAVE("CFM24VXX_I2C::Read (byte): %x", (bool)(result == 0))
00346             return (bool)(result == 0);
00347         }
00348     
00349         DEBUG_LEAVE("CFM24VXX_I2C::Read (byte) (false)")
00350         return false;
00351     }
00352     
00353     bool CFM24VXX_I2C::Read(const short p_address, short *p_short, const CFM24VXX_I2C::Mode p_mode) {
00354         DEBUG_ENTER("CFM24VXX_I2C::Read (short): Memory address:0x%02x, Mode:%d", p_address, p_mode)
00355     
00356         // 1.Prepare buffer
00357         char i2cBuffer[2];
00358         // 1.1. Memory address
00359         i2cBuffer[0] = (unsigned char)(p_address >> 8);
00360         DEBUG("CFM24VXX_I2C::Read (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
00361         i2cBuffer[1] = (unsigned char)((unsigned char)p_address & 0xff);
00362         DEBUG("CFM24VXX_I2C::Read (short): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
00363     
00364         // 2. Send I2C start + memory address
00365         if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) {
00366             //wait(0.02);
00367             DEBUG("CFM24VXX_I2C::Read (short): Write memory done")
00368             // 2. Read data + I2C stop
00369             int result = _i2cInstance->read(_slaveAddress, i2cBuffer, 2);
00370             if (result == 0) {
00371                 DEBUG("CFM24VXX_I2C::Read (short): value: 0x%02x - 0x%02x", i2cBuffer[0], i2cBuffer[1])
00372                 if (p_mode ==  BigEndian) {
00373                     *p_short = (short)(i2cBuffer[0] << 8 | i2cBuffer[1]);
00374                 } else {
00375                     *p_short = (short)(i2cBuffer[1] << 8 | i2cBuffer[0]);
00376                 }
00377         
00378                 DEBUG_LEAVE("CFM24VXX_I2C::Read (short): 0x%04x", *p_short)
00379                 return true;
00380             }
00381         }
00382     
00383         DEBUG_LEAVE("CFM24VXX_I2C::Read (short) (false)")
00384         return false;
00385     }
00386     
00387     bool CFM24VXX_I2C::Read(const short p_address, int *p_int, const CFM24VXX_I2C::Mode p_mode) {
00388         DEBUG_ENTER("CFM24VXX_I2C::Read (int): Memory address:0x%02x, Mode:%d", p_address, p_mode)
00389     
00390         // 1.Prepare buffer
00391         char i2cBuffer[4];
00392         // 1.1. Memory address
00393         i2cBuffer[0] = (unsigned char)(p_address >> 8);
00394         DEBUG("CFM24VXX_I2C::Read (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
00395         i2cBuffer[1] = (unsigned char)((unsigned char)p_address & 0xff);
00396         DEBUG("CFM24VXX_I2C::Read (int): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
00397     
00398         // 2. Send I2C start + memory address
00399         if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) {
00400             //wait(0.02);
00401             DEBUG("CFM24VXX_I2C::Read (int): Write memory done")
00402             // 2. Read data + I2C stop
00403             int result = _i2cInstance->read(_slaveAddress, i2cBuffer, 4);
00404             if (result == 0) {
00405                 DEBUG("CFM24VXX_I2C::Read (int): value: 0x%02x - 0x%02x - 0x%02x - 0x%02x", i2cBuffer[0], i2cBuffer[1], i2cBuffer[2], i2cBuffer[3])
00406                 //wait(0.02);
00407                 if (p_mode ==  BigEndian) {
00408                     *p_int = (int)(i2cBuffer[0] << 24 | i2cBuffer[1] << 16 | i2cBuffer[2] << 8 | i2cBuffer[3]);
00409                 } else {
00410                     *p_int = (int)(i2cBuffer[3] << 24 | i2cBuffer[2] << 16 | i2cBuffer[1] << 8 | i2cBuffer[0]);
00411                 }
00412     
00413                 DEBUG_LEAVE("CFM24VXX_I2C::Read (int): %d", *p_int)
00414                 return true;
00415             }
00416     
00417             DEBUG_LEAVE("CFM24VXX_I2C::Read (int):false")
00418             return false;
00419         }
00420     
00421         DEBUG_LEAVE("CFM24VXX_I2C::Read (int) (false)")
00422         return false;
00423     }
00424     
00425     bool CFM24VXX_I2C::Read(const short p_address, std::vector<unsigned char> & p_datas, const bool p_readLengthFirst, const int p_length2write) {
00426         DEBUG_ENTER("CFM24VXX_I2C::Read (vector): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write)
00427     
00428         // 1.Prepare buffer
00429         short address = p_address;
00430         int length = 0;
00431         if (p_readLengthFirst) {
00432             if (!Read(address, &length)) { // Read the length in big endian mode
00433                 DEBUG_LEAVE("CFM24VXX_I2C::Read (vector) Failed to read length")
00434                 return false;
00435             }
00436             DEBUG("CFM24VXX_I2C::Read (vector): length= %d", length)
00437             if (length == 0) {
00438                 return true;
00439             }
00440             address += 4; // Skip the length value 
00441             length -= 4; // length is the size of (string length + string)
00442         } else {
00443             if (p_length2write == -1) {
00444                 length = p_datas.size();
00445             } else {
00446                 length = p_length2write;
00447             }
00448         }
00449         DEBUG("CFM24VXX_I2C::Read (vector): length= %d", length)
00450     
00451         // 2. Memory address
00452         char i2cBuffer[2];
00453         i2cBuffer[0] = (unsigned char)(address >> 8);
00454         DEBUG("CFM24VXX_I2C::Read (vector): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
00455         i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
00456         DEBUG("CFM24VXX_I2C::Read (vector): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
00457     
00458         // 3. Send I2C start + memory address
00459         if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) {
00460             //wait(0.02);
00461             DEBUG("CFM24VXX_I2C::Read (vector): Write memory done")
00462             // 4. read data + I2C stop
00463             unsigned char buffer[length];
00464             int result = _i2cInstance->read(_slaveAddress, (char *)buffer, length);
00465             //wait(0.02);
00466             if (result == 0) {
00467                 p_datas.assign(buffer, buffer + length);
00468     
00469                 DEBUG_LEAVE("CFM24VXX_I2C::Read (vector): %x", (bool)(result == 0))
00470                 return (bool)(result == 0);
00471             }
00472         }
00473     
00474         DEBUG_LEAVE("CFM24VXX_I2C::Read (vector) (false)")
00475         return false;
00476     }
00477     
00478     bool CFM24VXX_I2C::Read(const short p_address, std::string & p_string, const bool p_readLengthFirst, const int p_length2write) {
00479         DEBUG_ENTER("CFM24VXX_I2C::Read (string): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write)
00480     
00481         // 1.Prepare buffer
00482         short address = p_address;
00483         int length = -1;
00484         if (p_readLengthFirst) { // The string was stored with its length
00485             if (!Read(address, &length)) { // Read the length as integer in big endian mode
00486                 DEBUG_ERROR("CFM24VXX_I2C::Read (string): Failed to read length")
00487                 return false;
00488             }
00489             //wait(0.02);
00490             DEBUG("CFM24VXX_I2C::Read (string): length=%d", length)
00491             if (length == 0) {
00492                 DEBUG_ERROR("CFM24VXX_I2C::Read (string): empty")
00493                 return true;
00494             }
00495             address += 4; // Skip the length value size 
00496             length -= 4; // length is the size of (string length + string)
00497         } else { // The string length is provided by p_length2write parameter
00498             if (p_length2write == -1) {
00499                 length = p_string.size();
00500             } else {
00501                 length = p_length2write;
00502                 p_string.resize(p_length2write);
00503             }
00504         }
00505         DEBUG("CFM24VXX_I2C::Read (string): Address=0x%02x - Length=%d", address, length)
00506     
00507         // 2. Memory address
00508         char i2cBuffer[2];
00509         i2cBuffer[0] = (unsigned char)(address >> 8);
00510         DEBUG("CFM24VXX_I2C::Read (string): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
00511         i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
00512         DEBUG("CFM24VXX_I2C::Read (string): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
00513     
00514         // 3. Send I2C start + memory address with repeat start
00515         if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) {
00516             //wait(0.02);
00517             DEBUG("CFM24VXX_I2C::Read (string): Write memory done")
00518             // 4. Read data + I2C stop
00519             char buffer[length];
00520             int result = _i2cInstance->read(_slaveAddress, (char *)buffer, length);
00521             if (result == 0) {
00522                 p_string.assign(buffer, length);
00523         
00524                 return true;
00525             }
00526         }
00527         
00528         DEBUG_LEAVE("CFM24VXX_I2C::Read (string) (false)")
00529         return false;
00530     }
00531     
00532     bool CFM24VXX_I2C::Read(const short p_address, char *p_string, const bool p_storeLength, const int p_length2write) {
00533         DEBUG_ENTER("CFM24VXX_I2C::Read (char *): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_storeLength, p_length2write)
00534     
00535         // 1.Prepare buffer
00536         short address = p_address;
00537         int length = -1;
00538         if (p_storeLength) { // The string was stored with its length
00539             if (!Read(address, &length)) { // Read the length as integer in big endian mode
00540                 DEBUG_ERROR("CFM24VXX_I2C::Read (char *): Failed to read length")
00541                 return false;
00542             }
00543             //wait(0.02);
00544             DEBUG("CFM24VXX_I2C::Read (char *): length=%d", length)
00545             if (length == 0) {
00546                 DEBUG_ERROR("CFM24VXX_I2C::Read (char *): empty")
00547                 return true;
00548             }
00549             address += 4; // Skip the length value size 
00550             length -= 4; // length is the size of (string length + string)
00551         } else { // The string length is provided by p_length2write parameter
00552             if (p_length2write == -1) {
00553                 DEBUG_ERROR("CFM24VXX_I2C::Read (char *): undefined length")
00554                 return false;
00555             } else {
00556                 length = p_length2write;
00557             }
00558         }
00559         DEBUG("CFM24VXX_I2C::Read (char *): Address=0x%02x - Length=%d", address, length)
00560     
00561         // 2. Memory address
00562         char i2cBuffer[2];
00563         i2cBuffer[0] = (unsigned char)(address >> 8);
00564         DEBUG("CFM24VXX_I2C::Read (char *): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
00565         i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
00566         DEBUG("CFM24VXX_I2C::Read (char *): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
00567     
00568         // 3. Send I2C start + memory address with repeat start
00569         if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) {
00570             //wait(0.02);
00571             DEBUG("CFM24VXX_I2C::Read (char *): Write memory done")
00572             // 4. Read data + I2C stop
00573             char buffer[length];
00574             int result = _i2cInstance->read(_slaveAddress, buffer, length);
00575             memcpy((void *)p_string, (const void *)buffer, length);
00576 
00577             DEBUG_LEAVE("CFM24VXX_I2C::Read (char *): %x", (bool)(result == 0))
00578             return (bool)(result == 0);
00579         }
00580                 
00581         DEBUG_LEAVE("CFM24VXX_I2C::Read (char *) (false)")
00582         return false;
00583     }
00584     
00585     unsigned char CFM24VXX_I2C::ChecksumSN(const unsigned char *pdatas, const unsigned int length) {
00586         DEBUG_ENTER("CFM24VXX_I2C::ChecksumSN")
00587    
00588         unsigned char crctable[256] = {
00589             0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15,
00590             0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,
00591             0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65,
00592             0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,
00593             0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5,
00594             0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,
00595             0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85,
00596             0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,
00597             0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2,
00598             0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,
00599             0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2,
00600             0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,
00601             0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32,
00602             0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,
00603             0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42,
00604             0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,
00605             0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C,
00606             0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,
00607             0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC,
00608             0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,
00609             0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C,
00610             0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,
00611             0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C,
00612             0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,
00613             0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B,
00614             0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,
00615             0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B,
00616             0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,
00617             0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB,
00618             0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,
00619             0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB,
00620             0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3
00621         };
00622         unsigned char crc = 0x00;
00623         unsigned int length_ = length;
00624         unsigned char *pdata = (unsigned char *)pdatas;
00625         while (length_-- != 0) {
00626             crc = crctable[crc ^ *pdata++];
00627             DEBUG("CFM24VXX_I2C::ChecksumSN: current checksum= 0x%02x - pdata:%08x", crc, pdata)
00628         }
00629         
00630         DEBUG_LEAVE("CFM24VXX_I2C::ChecksumSN: 0x%02x", crc)
00631         return crc;
00632     }
00633     
00634 #if defined(__DEBUG)
00635     void CFM24VXX_I2C::DumpMemoryArea(const int p_address, const int p_count) {
00636         DEBUG_ENTER("CFM24VXX_I2C::DumpMemoryArea: %d - %d", p_address, p_count)
00637     
00638         DEBUG("CFM24VXX_I2C::DumpMemoryArea: Reading datas...");
00639         std::vector<unsigned char> datas(p_count);
00640         if (!Read(p_address, datas, false)) { // Read bytes, including the lenght indication, buffer size is not set before the call
00641             std::cout << "CFM24VXX_I2C::DumpMemoryArea: read failed\r" << std::endl;
00642         } else {
00643             std::cout << "CFM24VXX_I2C::DumpMemoryArea: Read bytes:\r" << std::endl;
00644             HEXADUMP(&datas[0], p_count);
00645             std::cout << "\r" << std::endl;
00646         }
00647     }
00648 #endif // _DEBUG
00649 
00650 } // End of namespace _FM24VXX_I2C