Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
Generated on Wed Jul 13 2022 23:41:03 by
1.7.2
Ramtron FM24Vxx F-RAM