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

Fork of 24LCxx_I2C by Yann Garcia

Committer:
charly
Date:
Tue Dec 23 17:21:25 2014 +0000
Revision:
4:2add27250e69
Parent:
3:fc3eb4d2b07e
take care of page boundaries when writing to EEPROM

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Yann 0:21c698aa86f6 1 /* mbed simplified access to Microchip 24LCxx Serial EEPROM devices (I2C)
Yann 0:21c698aa86f6 2 * Copyright (c) 2010-2012 ygarcia, MIT License
Yann 0:21c698aa86f6 3 *
charly 4:2add27250e69 4 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
charly 4:2add27250e69 5 * and associated documentation files (the "Software"), to deal in the Software without restriction,
charly 4:2add27250e69 6 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
charly 4:2add27250e69 7 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Yann 0:21c698aa86f6 8 * furnished to do so, subject to the following conditions:
Yann 0:21c698aa86f6 9 *
charly 4:2add27250e69 10 * The above copyright notice and this permission notice shall be included in all copies or
Yann 0:21c698aa86f6 11 * substantial portions of the Software.
Yann 0:21c698aa86f6 12 *
charly 4:2add27250e69 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
charly 4:2add27250e69 14 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
charly 4:2add27250e69 15 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
charly 4:2add27250e69 16 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Yann 0:21c698aa86f6 17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Yann 0:21c698aa86f6 18 */
Yann 0:21c698aa86f6 19 #include <iostream>
Yann 0:21c698aa86f6 20 #include <sstream>
Yann 0:21c698aa86f6 21
Yann 0:21c698aa86f6 22 #include "24LCxx_I2C.h"
Yann 0:21c698aa86f6 23
charly 4:2add27250e69 24 namespace _24LCXX_I2C
charly 4:2add27250e69 25 {
Yann 0:21c698aa86f6 26
charly 4:2add27250e69 27 unsigned char C24LCXX_I2C::I2CModuleRefCounter = 0;
Yann 0:21c698aa86f6 28
charly 4:2add27250e69 29 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,
charly 4:2add27250e69 30 const uint32_t deviceSize, const uint8_t pageSize) : _internalId("")
charly 4:2add27250e69 31 {
charly 4:2add27250e69 32 DEBUG_ENTER("C24LCXX_I2C")
charly 4:2add27250e69 33
charly 4:2add27250e69 34 if (C24LCXX_I2C::I2CModuleRefCounter != 0) {
charly 4:2add27250e69 35 error("C24LCXX_I2C: Wrong params");
charly 4:2add27250e69 36 }
Yann 0:21c698aa86f6 37 #ifdef __DEBUG
charly 4:2add27250e69 38 std::ostringstream out(std::ostringstream::out);
charly 4:2add27250e69 39 out << "C24LCXX_I2C #" << C24LCXX_I2C::I2CModuleRefCounter;
charly 4:2add27250e69 40 _internalId.assign(out.str());
charly 4:2add27250e69 41 DEBUG("C24LCXX_I2C: _internalId='%s'", _internalId.c_str())
Yann 0:21c698aa86f6 42 #endif // __DEBUG
charly 4:2add27250e69 43 _i2cInstance = new I2C(p_sda, p_scl); //, "24LCxx_I2C");
charly 4:2add27250e69 44 C24LCXX_I2C::I2CModuleRefCounter += 1;
charly 4:2add27250e69 45 DEBUG_ENTER("C24LCXX_I2C: refCounter=%d", C24LCXX_I2C::I2CModuleRefCounter)
charly 4:2add27250e69 46
charly 4:2add27250e69 47 _slaveAddress = (p_address << 1) | 0xa0; // Slave address format is: 1 0 1 0 A3 A2 A1 R/W
charly 4:2add27250e69 48 DEBUG("C24LCXX_I2C: I2C slave adress: 0x%02x", _slaveAddress)
charly 4:2add27250e69 49 _i2cInstance->frequency(p_frequency); // Set the frequency of the I2C interface
charly 4:2add27250e69 50 if (p_wp != NC) {
charly 4:2add27250e69 51 DEBUG("C24LCXX_I2C: WP managed");
charly 4:2add27250e69 52 _wp = new DigitalOut(p_wp);
charly 4:2add27250e69 53 _wp->write(0); // Disable write protect
charly 4:2add27250e69 54 } else {
charly 4:2add27250e69 55 DEBUG("C24LCXX_I2C: WP not managed");
charly 4:2add27250e69 56 _wp = NULL; // Not used
charly 4:2add27250e69 57 }
charly 4:2add27250e69 58
charly 4:2add27250e69 59 DEBUG("C24LCXX_I2C: Device-Size %i kbit", deviceSize);
charly 4:2add27250e69 60
charly 4:2add27250e69 61 DEBUG("C24LCXX_I2C: Page-Size %i Bytes", pageSize);
charly 4:2add27250e69 62
charly 4:2add27250e69 63 _pageSize = pageSize; //TODO Check for valid values
charly 4:2add27250e69 64 _deviceSize = deviceSize; //TODO Check for valid values
charly 4:2add27250e69 65
charly 4:2add27250e69 66 DEBUG_LEAVE("C24LCXX_I2C")
charly 4:2add27250e69 67 }
Yann 0:21c698aa86f6 68
charly 4:2add27250e69 69 C24LCXX_I2C::~C24LCXX_I2C()
charly 4:2add27250e69 70 {
charly 4:2add27250e69 71 DEBUG_ENTER("~C24LCXX_I2C")
charly 4:2add27250e69 72
charly 4:2add27250e69 73 // Release I2C instance
charly 4:2add27250e69 74 DEBUG_ENTER("~C24LCXX_I2C: refCounter=%d", C24LCXX_I2C::I2CModuleRefCounter)
charly 4:2add27250e69 75 C24LCXX_I2C::I2CModuleRefCounter -= 1;
charly 4:2add27250e69 76 if (C24LCXX_I2C::I2CModuleRefCounter == 0) {
charly 4:2add27250e69 77 delete _i2cInstance;
charly 4:2add27250e69 78 _i2cInstance = NULL;
charly 4:2add27250e69 79 }
charly 4:2add27250e69 80 // Release _wp if required
charly 4:2add27250e69 81 if (_wp != NULL) {
charly 4:2add27250e69 82 _wp->write(0);
charly 4:2add27250e69 83 delete _wp;
charly 4:2add27250e69 84 }
charly 4:2add27250e69 85
charly 4:2add27250e69 86 DEBUG_LEAVE("~C24LCXX_I2C")
charly 4:2add27250e69 87 }
charly 4:2add27250e69 88
charly 4:2add27250e69 89 bool C24LCXX_I2C::WriteProtect(const bool p_writeProtect)
charly 4:2add27250e69 90 {
charly 4:2add27250e69 91 if (_wp != NULL) {
charly 4:2add27250e69 92 DEBUG("WP set to: %x", (int)p_writeProtect)
charly 4:2add27250e69 93 _wp->write((int)(p_writeProtect));
charly 4:2add27250e69 94 return true;
Yann 0:21c698aa86f6 95 }
Yann 0:21c698aa86f6 96
charly 4:2add27250e69 97 return false;
charly 4:2add27250e69 98 }
charly 4:2add27250e69 99
charly 4:2add27250e69 100 bool C24LCXX_I2C::EraseMemoryArea(const short p_startAddress, const int p_count, const unsigned char p_pattern)
charly 4:2add27250e69 101 {
charly 4:2add27250e69 102 DEBUG_ENTER("C24LCXX_I2C::EraseMemoryArea: 0x%02x - %d - 0x%02x", p_startAddress, p_count, p_pattern)
charly 4:2add27250e69 103
charly 4:2add27250e69 104 std::vector<unsigned char> eraseBuffer(p_count, p_pattern);
charly 4:2add27250e69 105 return Write(p_startAddress, eraseBuffer, false);
charly 4:2add27250e69 106 }
charly 4:2add27250e69 107
charly 4:2add27250e69 108 bool C24LCXX_I2C::Write(const short p_address, const unsigned char p_byte)
charly 4:2add27250e69 109 {
charly 4:2add27250e69 110 DEBUG_ENTER("C24LCXX_I2C::Write (byte): Memory address: 0x%02x - 0x%02x", p_address, p_byte)
charly 4:2add27250e69 111
charly 4:2add27250e69 112 // 1.Prepare buffer
charly 4:2add27250e69 113 char i2cBuffer[3]; // Memory address + one byte of data
charly 4:2add27250e69 114 // 1.1. Memory address
charly 4:2add27250e69 115 //short address = p_address + 1; // Index start to 1
charly 4:2add27250e69 116 short address = p_address; // no Index + 1
charly 4:2add27250e69 117 i2cBuffer[0] = (unsigned char)(address >> 8);
charly 4:2add27250e69 118 DEBUG("C24LCXX_I2C::Write (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
charly 4:2add27250e69 119 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
charly 4:2add27250e69 120 DEBUG("C24LCXX_I2C::Write (byte): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
charly 4:2add27250e69 121 // 1.2. Datas
charly 4:2add27250e69 122 i2cBuffer[2] = p_byte;
charly 4:2add27250e69 123 DEBUG("C24LCXX_I2C::Write (byte): value=0x%02x", i2cBuffer[2])
charly 4:2add27250e69 124
charly 4:2add27250e69 125 // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
charly 4:2add27250e69 126 int result = _i2cInstance->write(_slaveAddress, i2cBuffer, 3);
charly 4:2add27250e69 127 wait(0.02);
charly 4:2add27250e69 128
charly 4:2add27250e69 129 DEBUG_LEAVE("C24LCXX_I2C::Write (byte) %x", (bool)(result == 0))
charly 4:2add27250e69 130 return (bool)(result == 0);
charly 4:2add27250e69 131 }
charly 4:2add27250e69 132
charly 4:2add27250e69 133 bool C24LCXX_I2C::Write(const short p_address, const short p_short, const C24LCXX_I2C::Mode p_mode)
charly 4:2add27250e69 134 {
charly 4:2add27250e69 135 DEBUG_ENTER("C24LCXX_I2C::Write (short): Memory address:0x%02x, Mode:%d", p_address, p_mode)
charly 4:2add27250e69 136
charly 4:2add27250e69 137 // 1.Prepare buffer
charly 4:2add27250e69 138 char i2cBuffer[4]; // Memory address + one short (2 bytes)
charly 4:2add27250e69 139 // 1.1. Memory address
charly 4:2add27250e69 140 //short address = p_address + 1; // Index start to 1
charly 4:2add27250e69 141 short address = p_address; // no Index+1
charly 4:2add27250e69 142 i2cBuffer[0] = (unsigned char)(address >> 8);
charly 4:2add27250e69 143 DEBUG("C24LCXX_I2C::Write (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
charly 4:2add27250e69 144 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
charly 4:2add27250e69 145 DEBUG("C24LCXX_I2C::Write (short): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
charly 4:2add27250e69 146 // 1.2. Datas
charly 4:2add27250e69 147 if (p_mode == BigEndian) {
charly 4:2add27250e69 148 i2cBuffer[2] = (unsigned char)(p_short >> 8);
charly 4:2add27250e69 149 i2cBuffer[3] = (unsigned char)((unsigned char)p_short & 0xff);
charly 4:2add27250e69 150 } else {
charly 4:2add27250e69 151 i2cBuffer[2] = (unsigned char)((unsigned char)p_short & 0xff);
charly 4:2add27250e69 152 i2cBuffer[3] = (unsigned char)(p_short >> 8);
charly 4:2add27250e69 153 }
charly 4:2add27250e69 154 DEBUG("C24LCXX_I2C::Write (short): value=0x%02x%02x", i2cBuffer[2], i2cBuffer[3])
charly 4:2add27250e69 155
charly 4:2add27250e69 156 // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
charly 4:2add27250e69 157 int result = _i2cInstance->write(_slaveAddress, i2cBuffer, 4);
charly 4:2add27250e69 158 wait(0.02);
charly 4:2add27250e69 159
charly 4:2add27250e69 160 DEBUG_LEAVE("C24LCXX_I2C::Write (short) %x", (bool)(result == 0))
charly 4:2add27250e69 161 return (bool)(result == 0);
charly 4:2add27250e69 162 }
charly 4:2add27250e69 163
charly 4:2add27250e69 164 bool C24LCXX_I2C::Write(const short p_address, const int p_int, const C24LCXX_I2C::Mode p_mode)
charly 4:2add27250e69 165 {
charly 4:2add27250e69 166 DEBUG_ENTER("C24LCXX_I2C::Write (int): Memory address:0x%02x, Mode:%d", p_address, p_mode)
charly 4:2add27250e69 167
charly 4:2add27250e69 168 // 1.Prepare buffer
charly 4:2add27250e69 169 char i2cBuffer[6]; // Memory address + one integer (4 bytes)
charly 4:2add27250e69 170 // 1.1. Memory address
charly 4:2add27250e69 171 //short address = p_address + 1; // Index start to 1
charly 4:2add27250e69 172 short address = p_address; // no Index+1
charly 4:2add27250e69 173 i2cBuffer[0] = (unsigned char)(address >> 8);
charly 4:2add27250e69 174 DEBUG("C24LCXX_I2C::Write (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
charly 4:2add27250e69 175 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
charly 4:2add27250e69 176 DEBUG("C24LCXX_I2C::Write (int): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
charly 4:2add27250e69 177 // 1.2. Datas
charly 4:2add27250e69 178 if (p_mode == BigEndian) {
charly 4:2add27250e69 179 i2cBuffer[2] = (unsigned char)(p_int >> 24);
charly 4:2add27250e69 180 i2cBuffer[3] = (unsigned char)(p_int >> 16);
charly 4:2add27250e69 181 i2cBuffer[4] = (unsigned char)(p_int >> 8);
charly 4:2add27250e69 182 i2cBuffer[5] = (unsigned char)((unsigned char)p_int & 0xff);
charly 4:2add27250e69 183 } else {
charly 4:2add27250e69 184 i2cBuffer[2] = (unsigned char)((unsigned char)p_int & 0xff);
charly 4:2add27250e69 185 i2cBuffer[3] = (unsigned char)(p_int >> 8);
charly 4:2add27250e69 186 i2cBuffer[4] = (unsigned char)(p_int >> 16);
charly 4:2add27250e69 187 i2cBuffer[5] = (unsigned char)(p_int >> 24);
charly 4:2add27250e69 188 }
charly 4:2add27250e69 189 DEBUG("C24LCXX_I2C::Write (int): value=0x%02x%02x%02x%02x", i2cBuffer[2], i2cBuffer[3], i2cBuffer[4], i2cBuffer[5])
charly 4:2add27250e69 190
charly 4:2add27250e69 191 // 2. Send I2C start + I2C address + Memory Address + Datas + I2C stop
charly 4:2add27250e69 192 int result = _i2cInstance->write(_slaveAddress, i2cBuffer, 6);
charly 4:2add27250e69 193 wait(0.02);
charly 4:2add27250e69 194
charly 4:2add27250e69 195 DEBUG_LEAVE("C24LCXX_I2C::Write (int) %x", (bool)(result == 0))
charly 4:2add27250e69 196 return (bool)(result == 0);
charly 4:2add27250e69 197 }
charly 4:2add27250e69 198
charly 4:2add27250e69 199 bool C24LCXX_I2C::Write(const short p_address, const std::string & p_string, const bool p_storeLength, const int p_length2write)
charly 4:2add27250e69 200 {
charly 4:2add27250e69 201 DEBUG_ENTER("C24LCXX_I2C::Write (std::string)")
charly 4:2add27250e69 202 return Write(p_address, p_string.c_str(), p_storeLength, p_length2write);
charly 4:2add27250e69 203 }
charly 4:2add27250e69 204
charly 4:2add27250e69 205 bool C24LCXX_I2C::Write(const short p_address, const std::vector<unsigned char> & p_datas, const bool p_storeLength, const int p_length2write)
charly 4:2add27250e69 206 {
charly 4:2add27250e69 207 DEBUG_ENTER("C24LCXX_I2C::Write (std::vector)")
charly 4:2add27250e69 208
charly 4:2add27250e69 209 int length = (p_length2write == -1) ? p_datas.size() : p_length2write;
charly 4:2add27250e69 210 unsigned char array[length];
charly 4:2add27250e69 211 std::copy(p_datas.begin(), p_datas.end(), array);
charly 4:2add27250e69 212 bool result = Write(p_address, array, p_storeLength, length);
charly 4:2add27250e69 213 wait(0.02);
charly 4:2add27250e69 214
charly 4:2add27250e69 215 DEBUG_LEAVE("C24LCXX_I2C::Write (std::vector): %d", result)
charly 4:2add27250e69 216 return result;
charly 4:2add27250e69 217 }
charly 4:2add27250e69 218
charly 4:2add27250e69 219 bool C24LCXX_I2C::Write(const short p_address, const char * p_datas, const bool p_storeLength, const int p_length2write)
charly 4:2add27250e69 220 {
charly 4:2add27250e69 221 DEBUG_ENTER("C24LCXX_I2C::Write (char *): Memory address: 0x%02x - %x - %d", p_address, p_storeLength, p_length2write)
charly 4:2add27250e69 222
charly 4:2add27250e69 223 // 1.Prepare buffer
charly 4:2add27250e69 224 int length = (p_length2write == -1) ? strlen(p_datas) : p_length2write;
charly 4:2add27250e69 225 if (p_storeLength) {
charly 4:2add27250e69 226 length += 4; // Add four bytes for the length as integer
charly 4:2add27250e69 227 }
charly 4:2add27250e69 228 DEBUG("C24LCXX_I2C::Write (char *): length:%d", length)
charly 4:2add27250e69 229
charly 4:2add27250e69 230 char i2cBuffer[2 + length];
charly 4:2add27250e69 231 // 1.1. Memory address
charly 4:2add27250e69 232 //short address = p_address + 1; // Index start to 1
charly 4:2add27250e69 233 short address = p_address; // no Index+1
charly 4:2add27250e69 234 // i2cBuffer[0] = (unsigned char)(address >> 8);
charly 4:2add27250e69 235 // DEBUG("C24LCXX_I2C::Write (char *): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
charly 4:2add27250e69 236 // i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
charly 4:2add27250e69 237 // DEBUG("C24LCXX_I2C::Write (char *): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
charly 4:2add27250e69 238 // 1.2. Datas
charly 4:2add27250e69 239 if (p_storeLength) {
charly 4:2add27250e69 240 // Fill the length
charly 4:2add27250e69 241 i2cBuffer[2] = (unsigned char)(length >> 24);
charly 4:2add27250e69 242 i2cBuffer[3] = (unsigned char)(length >> 16);
charly 4:2add27250e69 243 i2cBuffer[4] = (unsigned char)(length >> 8);
charly 4:2add27250e69 244 i2cBuffer[5] = (unsigned char)((unsigned char)length & 0xff);
charly 4:2add27250e69 245 for (int i = 0; i < length - 4; i++) {
charly 4:2add27250e69 246 i2cBuffer[6 + i] = *(p_datas + i);
Yann 0:21c698aa86f6 247 }
charly 4:2add27250e69 248 } else { // The length was not stored
charly 4:2add27250e69 249 for (int i = 0; i < length; i++) {
charly 4:2add27250e69 250 i2cBuffer[2 + i] = *(p_datas + i);
Yann 0:21c698aa86f6 251 }
charly 4:2add27250e69 252 }
charly 4:2add27250e69 253
charly 4:2add27250e69 254 //HEXADUMP((unsigned char *) i2cBuffer+2, length);
charly 4:2add27250e69 255
charly 4:2add27250e69 256 /*
charly 4:2add27250e69 257 // 2. Send I2C start + Memory Address
charly 4:2add27250e69 258 _i2cInstance->write(_slaveAddress, i2cBuffer, 2, true);
charly 4:2add27250e69 259 wait(0.02);
charly 4:2add27250e69 260
charly 4:2add27250e69 261 // 3. Send Datas + I2C stop
charly 4:2add27250e69 262 int result = _i2cInstance->write(_slaveAddress, i2cBuffer+2, length);
charly 4:2add27250e69 263 wait(0.02);
charly 4:2add27250e69 264 */
charly 4:2add27250e69 265 //write pages to EEPROM
charly 4:2add27250e69 266 int result = i2cWrite(address,i2cBuffer+2, length);
charly 4:2add27250e69 267 wait(0.02);
charly 4:2add27250e69 268
charly 4:2add27250e69 269 DEBUG_LEAVE("C24LCXX_I2C::Write (char *) %x", (bool)(result == 0))
charly 4:2add27250e69 270 return (bool)(result == 0);
charly 4:2add27250e69 271 }
charly 4:2add27250e69 272
charly 4:2add27250e69 273 bool C24LCXX_I2C::Write(const short p_address, const unsigned char *p_datas, const bool p_storeLength, const int p_length2write)
charly 4:2add27250e69 274 {
charly 4:2add27250e69 275 DEBUG_ENTER("C24LCXX_I2C::Write (byte *): Memory address: 0x%02x - %x - %d", p_address, p_storeLength, p_length2write)
charly 4:2add27250e69 276 return Write(p_address, (const char *)p_datas, p_storeLength, p_length2write);
charly 4:2add27250e69 277 }
charly 4:2add27250e69 278
charly 4:2add27250e69 279
charly 4:2add27250e69 280 int C24LCXX_I2C::i2cWrite(short address, const char *data, int length)
charly 4:2add27250e69 281 {
charly 4:2add27250e69 282 //write to EEPROM in chunks of pagesize
charly 4:2add27250e69 283 int rv = 0;
charly 4:2add27250e69 284 while (length > 0) {
charly 4:2add27250e69 285 int bytesUntilPageBoundary = _pageSize - address % _pageSize;
charly 4:2add27250e69 286 int cnt = min(length, bytesUntilPageBoundary);
charly 4:2add27250e69 287 char i2cBuffer[2 + _pageSize];
charly 4:2add27250e69 288 // 1.1. Memory address
charly 4:2add27250e69 289
charly 4:2add27250e69 290 i2cBuffer[0] = (unsigned char)(address >> 8);
charly 4:2add27250e69 291 DEBUG("C24LCXX_I2C::i2cWrite (char *): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
charly 4:2add27250e69 292 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
charly 4:2add27250e69 293 DEBUG("C24LCXX_I2C::i2cWrite (char *): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
charly 4:2add27250e69 294 DEBUG("C24LCXX_I2C::i2cWrite (char *): length : %i", cnt)
charly 4:2add27250e69 295
charly 4:2add27250e69 296 //Copy data after address
charly 4:2add27250e69 297 for (int i = 0; i < cnt; i++) {
charly 4:2add27250e69 298 i2cBuffer[2 + i] = *(data + i);
charly 4:2add27250e69 299 }
charly 4:2add27250e69 300
charly 4:2add27250e69 301 //HEXADUMP((unsigned char *) i2cBuffer, cnt+2);
charly 4:2add27250e69 302 // Write data; max until page boundary
charly 4:2add27250e69 303 int rv = _i2cInstance->write(_slaveAddress, i2cBuffer, cnt+2);
charly 4:2add27250e69 304
charly 4:2add27250e69 305 if (rv != 0) return rv;
charly 4:2add27250e69 306
charly 4:2add27250e69 307 address += cnt;
charly 4:2add27250e69 308 data += cnt;
charly 4:2add27250e69 309 length -= cnt;
Yann 0:21c698aa86f6 310 }
charly 4:2add27250e69 311 return rv;
charly 4:2add27250e69 312 }
charly 4:2add27250e69 313
charly 4:2add27250e69 314
charly 4:2add27250e69 315 bool C24LCXX_I2C::Read(const short p_address, unsigned char * p_byte)
charly 4:2add27250e69 316 {
charly 4:2add27250e69 317 DEBUG_ENTER("C24LCXX_I2C::Read (byte): Memory address:0x%02x", p_address)
charly 4:2add27250e69 318
charly 4:2add27250e69 319 // 1.Prepare buffer
charly 4:2add27250e69 320 char i2cBuffer[2];
charly 4:2add27250e69 321 // 1.1. Memory address
charly 4:2add27250e69 322 i2cBuffer[0] = (unsigned char)(p_address >> 8);
charly 4:2add27250e69 323 DEBUG("C24LCXX_I2C::Read (byte): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
charly 4:2add27250e69 324 i2cBuffer[1] = (unsigned char)((unsigned char)p_address & 0xff);
charly 4:2add27250e69 325 DEBUG("C24LCXX_I2C::Read (byte): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
charly 4:2add27250e69 326
charly 4:2add27250e69 327 // 2. Send I2C start + memory address
charly 4:2add27250e69 328 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) {
charly 4:2add27250e69 329 wait(0.02);
charly 4:2add27250e69 330 DEBUG("C24LCXX_I2C::Read (byte): Write memory done")
charly 4:2add27250e69 331 // 2. Read data + I2C stop
charly 4:2add27250e69 332 int result = _i2cInstance->read(_slaveAddress, (char *)p_byte, 1);
charly 4:2add27250e69 333 wait(0.02);
charly 4:2add27250e69 334
charly 4:2add27250e69 335 DEBUG_LEAVE("C24LCXX_I2C::Read (byte): %x", (bool)(result == 0))
charly 4:2add27250e69 336 return (bool)(result == 0);
charly 4:2add27250e69 337 }
charly 4:2add27250e69 338
charly 4:2add27250e69 339 DEBUG_LEAVE("C24LCXX_I2C::Read (byte) (false)")
charly 4:2add27250e69 340 return false;
charly 4:2add27250e69 341 }
charly 4:2add27250e69 342
charly 4:2add27250e69 343 bool C24LCXX_I2C::Read(const short p_address, short *p_short, const C24LCXX_I2C::Mode p_mode)
charly 4:2add27250e69 344 {
charly 4:2add27250e69 345 DEBUG_ENTER("C24LCXX_I2C::Read (short): Memory address:0x%02x, Mode:%d", p_address, p_mode)
charly 4:2add27250e69 346
charly 4:2add27250e69 347 // 1.Prepare buffer
charly 4:2add27250e69 348 char i2cBuffer[2];
charly 4:2add27250e69 349 // 1.1. Memory address
charly 4:2add27250e69 350 i2cBuffer[0] = (unsigned char)(p_address >> 8);
charly 4:2add27250e69 351 DEBUG("C24LCXX_I2C::Read (short): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
charly 4:2add27250e69 352 i2cBuffer[1] = (unsigned char)((unsigned char)p_address & 0xff);
charly 4:2add27250e69 353 DEBUG("C24LCXX_I2C::Read (short): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
charly 4:2add27250e69 354
charly 4:2add27250e69 355 // 2. Send I2C start + memory address
charly 4:2add27250e69 356 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) {
charly 4:2add27250e69 357 wait(0.02);
charly 4:2add27250e69 358 DEBUG("C24LCXX_I2C::Read (short): Write memory done")
charly 4:2add27250e69 359 // 2. Read data + I2C stop
charly 4:2add27250e69 360 int result = _i2cInstance->read(_slaveAddress, i2cBuffer, 2);
charly 4:2add27250e69 361 if (result == 0) {
charly 4:2add27250e69 362 DEBUG("C24LCXX_I2C::Read (short): value: 0x%02x - 0x%02x", i2cBuffer[0], i2cBuffer[1])
charly 4:2add27250e69 363 if (p_mode == BigEndian) {
charly 4:2add27250e69 364 *p_short = (short)(i2cBuffer[0] << 8 | i2cBuffer[1]);
charly 4:2add27250e69 365 } else {
charly 4:2add27250e69 366 *p_short = (short)(i2cBuffer[1] << 8 | i2cBuffer[0]);
charly 4:2add27250e69 367 }
charly 4:2add27250e69 368
charly 4:2add27250e69 369 DEBUG_LEAVE("C24LCXX_I2C::Read (short): 0x%04x", *p_short)
Yann 0:21c698aa86f6 370 return true;
Yann 0:21c698aa86f6 371 }
charly 4:2add27250e69 372 }
charly 4:2add27250e69 373
charly 4:2add27250e69 374 DEBUG_LEAVE("C24LCXX_I2C::Read (short) (false)")
charly 4:2add27250e69 375 return false;
charly 4:2add27250e69 376 }
charly 4:2add27250e69 377
charly 4:2add27250e69 378 bool C24LCXX_I2C::Read(const short p_address, int *p_int, const C24LCXX_I2C::Mode p_mode)
charly 4:2add27250e69 379 {
charly 4:2add27250e69 380 DEBUG_ENTER("C24LCXX_I2C::Read (int): Memory address:0x%02x, Mode:%d", p_address, p_mode)
charly 4:2add27250e69 381
charly 4:2add27250e69 382 // 1.Prepare buffer
charly 4:2add27250e69 383 char i2cBuffer[4];
charly 4:2add27250e69 384 // 1.1. Memory address
charly 4:2add27250e69 385 i2cBuffer[0] = (unsigned char)(p_address >> 8);
charly 4:2add27250e69 386 DEBUG("C24LCXX_I2C::Read (int): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
charly 4:2add27250e69 387 i2cBuffer[1] = (unsigned char)((unsigned char)p_address & 0xff);
charly 4:2add27250e69 388 DEBUG("C24LCXX_I2C::Read (int): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
charly 4:2add27250e69 389
charly 4:2add27250e69 390 // 2. Send I2C start + memory address
charly 4:2add27250e69 391 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) {
charly 4:2add27250e69 392 wait(0.02);
charly 4:2add27250e69 393 DEBUG("C24LCXX_I2C::Read (int): Write memory done")
charly 4:2add27250e69 394 // 2. Read data + I2C stop
charly 4:2add27250e69 395 int result = _i2cInstance->read(_slaveAddress, i2cBuffer, 4);
charly 4:2add27250e69 396 if (result == 0) {
charly 4:2add27250e69 397 DEBUG("C24LCXX_I2C::Read (int): value: 0x%02x - 0x%02x - 0x%02x - 0x%02x", i2cBuffer[0], i2cBuffer[1], i2cBuffer[2], i2cBuffer[3])
charly 4:2add27250e69 398 wait(0.02);
charly 4:2add27250e69 399 if (p_mode == BigEndian) {
charly 4:2add27250e69 400 *p_int = (int)(i2cBuffer[0] << 24 | i2cBuffer[1] << 16 | i2cBuffer[2] << 8 | i2cBuffer[3]);
charly 4:2add27250e69 401 } else {
charly 4:2add27250e69 402 *p_int = (int)(i2cBuffer[3] << 24 | i2cBuffer[2] << 16 | i2cBuffer[1] << 8 | i2cBuffer[0]);
charly 4:2add27250e69 403 }
charly 4:2add27250e69 404
charly 4:2add27250e69 405 DEBUG_LEAVE("C24LCXX_I2C::Read (int): %d", *p_int)
charly 4:2add27250e69 406 return true;
charly 4:2add27250e69 407 }
charly 4:2add27250e69 408
charly 4:2add27250e69 409 DEBUG_LEAVE("C24LCXX_I2C::Read (int):false")
Yann 0:21c698aa86f6 410 return false;
Yann 0:21c698aa86f6 411 }
Yann 0:21c698aa86f6 412
charly 4:2add27250e69 413 DEBUG_LEAVE("C24LCXX_I2C::Read (int) (false)")
charly 4:2add27250e69 414 return false;
charly 4:2add27250e69 415 }
charly 4:2add27250e69 416
charly 4:2add27250e69 417 bool C24LCXX_I2C::Read(const short p_address, std::vector<unsigned char> & p_datas, const bool p_readLengthFirst, const int p_length2write)
charly 4:2add27250e69 418 {
charly 4:2add27250e69 419 DEBUG_ENTER("C24LCXX_I2C::Read (vector): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write)
Yann 0:21c698aa86f6 420
charly 4:2add27250e69 421 // 1.Prepare buffer
charly 4:2add27250e69 422 short address = p_address;
charly 4:2add27250e69 423 int length = 0;
charly 4:2add27250e69 424 if (p_readLengthFirst) {
charly 4:2add27250e69 425 if (!Read(address, &length)) { // Read the length in big endian mode
charly 4:2add27250e69 426 DEBUG_LEAVE("C24LCXX_I2C::Read (vector) Failed to read length")
charly 4:2add27250e69 427 return false;
charly 4:2add27250e69 428 }
charly 4:2add27250e69 429 DEBUG("C24LCXX_I2C::Read (vector): length= %d", length)
charly 4:2add27250e69 430 if (length == 0) {
charly 4:2add27250e69 431 return true;
charly 4:2add27250e69 432 }
charly 4:2add27250e69 433 address += 4; // Skip the length value
charly 4:2add27250e69 434 length -= 4; // length is the size of (string length + string)
charly 4:2add27250e69 435 } else {
charly 4:2add27250e69 436 if (p_length2write == -1) {
charly 4:2add27250e69 437 length = p_datas.size();
charly 4:2add27250e69 438 } else {
charly 4:2add27250e69 439 length = p_length2write;
charly 4:2add27250e69 440 }
Yann 0:21c698aa86f6 441 }
charly 4:2add27250e69 442 DEBUG("C24LCXX_I2C::Read (vector): length= %d", length)
charly 4:2add27250e69 443
charly 4:2add27250e69 444 // 2. Memory address
charly 4:2add27250e69 445 char i2cBuffer[2];
charly 4:2add27250e69 446 i2cBuffer[0] = (unsigned char)(address >> 8);
charly 4:2add27250e69 447 DEBUG("C24LCXX_I2C::Read (vector): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
charly 4:2add27250e69 448 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
charly 4:2add27250e69 449 DEBUG("C24LCXX_I2C::Read (vector): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
charly 4:2add27250e69 450
charly 4:2add27250e69 451 // 3. Send I2C start + memory address
charly 4:2add27250e69 452 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) {
Yann 0:21c698aa86f6 453 wait(0.02);
charly 4:2add27250e69 454 DEBUG("C24LCXX_I2C::Read (vector): Write memory done")
charly 4:2add27250e69 455 // 4. read data + I2C stop
charly 4:2add27250e69 456 unsigned char buffer[length];
charly 4:2add27250e69 457 int result = _i2cInstance->read(_slaveAddress, (char *)buffer, length);
Yann 0:21c698aa86f6 458 wait(0.02);
charly 4:2add27250e69 459 if (result == 0) {
charly 4:2add27250e69 460 p_datas.assign(buffer, buffer + length);
charly 4:2add27250e69 461
charly 4:2add27250e69 462 DEBUG_LEAVE("C24LCXX_I2C::Read (vector): %x", (bool)(result == 0))
Yann 0:21c698aa86f6 463 return (bool)(result == 0);
Yann 0:21c698aa86f6 464 }
Yann 0:21c698aa86f6 465 }
charly 4:2add27250e69 466
charly 4:2add27250e69 467 DEBUG_LEAVE("C24LCXX_I2C::Read (vector) (false)")
charly 4:2add27250e69 468 return false;
charly 4:2add27250e69 469 }
charly 4:2add27250e69 470
charly 4:2add27250e69 471 bool C24LCXX_I2C::Read(const short p_address, std::string & p_string, const bool p_readLengthFirst, const int p_length2write)
charly 4:2add27250e69 472 {
charly 4:2add27250e69 473 DEBUG_ENTER("C24LCXX_I2C::Read (string): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write)
charly 4:2add27250e69 474
charly 4:2add27250e69 475 /* std::vector<unsigned char> datas;
charly 4:2add27250e69 476 if (Read(p_address, datas, p_readLengthFirst, p_length2write) == true) {
charly 4:2add27250e69 477 p_string.assign((char *)datas.begin(), datas.size());
charly 4:2add27250e69 478
Yann 0:21c698aa86f6 479 return true;
Yann 0:21c698aa86f6 480 }
charly 4:2add27250e69 481
charly 4:2add27250e69 482 DEBUG_LEAVE("C24LCXX_I2C::Read (string) (false)")
charly 4:2add27250e69 483 return false;
charly 4:2add27250e69 484 */
charly 4:2add27250e69 485
charly 4:2add27250e69 486 // 1.Prepare buffer
charly 4:2add27250e69 487 short address = p_address;
charly 4:2add27250e69 488 int length = -1;
charly 4:2add27250e69 489 if (p_readLengthFirst) { // The string was stored with its length
charly 4:2add27250e69 490 if (!Read(address, &length)) { // Read the length as integer in big endian mode
charly 4:2add27250e69 491 DEBUG_ERROR("C24LCXX_I2C::Read (string): Failed to read length")
charly 4:2add27250e69 492 return false;
charly 4:2add27250e69 493 }
charly 4:2add27250e69 494 wait(0.02);
charly 4:2add27250e69 495 DEBUG("C24LCXX_I2C::Read (string): length=%d", length)
charly 4:2add27250e69 496 if (length == 0) {
charly 4:2add27250e69 497 DEBUG_ERROR("C24LCXX_I2C::Read (string): empty")
charly 4:2add27250e69 498 return true;
Yann 0:21c698aa86f6 499 }
charly 4:2add27250e69 500 address += 4; // Skip the length value size
charly 4:2add27250e69 501 length -= 4; // length is the size of (string length + string)
charly 4:2add27250e69 502 } else { // The string length is provided by p_length2write parameter
charly 4:2add27250e69 503 if (p_length2write == -1) {
charly 4:2add27250e69 504 length = p_string.size();
charly 4:2add27250e69 505 } else {
charly 4:2add27250e69 506 length = p_length2write;
charly 4:2add27250e69 507 p_string.resize(p_length2write);
Yann 0:21c698aa86f6 508 }
Yann 0:21c698aa86f6 509 }
charly 4:2add27250e69 510 DEBUG("C24LCXX_I2C::Read (string): Address=0x%02x - Length=%d", address, length)
charly 4:2add27250e69 511
charly 4:2add27250e69 512 // 2. Memory address
charly 4:2add27250e69 513 char i2cBuffer[2];
charly 4:2add27250e69 514 i2cBuffer[0] = (unsigned char)(address >> 8);
charly 4:2add27250e69 515 DEBUG("C24LCXX_I2C::Read (string): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
charly 4:2add27250e69 516 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
charly 4:2add27250e69 517 DEBUG("C24LCXX_I2C::Read (string): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
Yann 0:21c698aa86f6 518
charly 4:2add27250e69 519 // 3. Send I2C start + memory address with repeat start
charly 4:2add27250e69 520 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) {
charly 4:2add27250e69 521 wait(0.02);
charly 4:2add27250e69 522 DEBUG("C24LCXX_I2C::Read (string): Write memory done")
charly 4:2add27250e69 523 // 4. Read data + I2C stop
charly 4:2add27250e69 524 char buffer[length];
charly 4:2add27250e69 525 int result = _i2cInstance->read(_slaveAddress, (char *)buffer, length);
charly 4:2add27250e69 526 if (result == 0) {
charly 4:2add27250e69 527 p_string.assign(buffer, length);
charly 4:2add27250e69 528
Yann 0:21c698aa86f6 529 return true;
Yann 0:21c698aa86f6 530 }
Yann 0:21c698aa86f6 531 }
Yann 0:21c698aa86f6 532
charly 4:2add27250e69 533 DEBUG_LEAVE("C24LCXX_I2C::Read (string) (false)")
charly 4:2add27250e69 534 return false;
charly 4:2add27250e69 535 }
charly 4:2add27250e69 536
charly 4:2add27250e69 537 bool C24LCXX_I2C::Read(const short p_address, unsigned char * p_datas, bool p_readLengthFirst , int p_length2write)
charly 4:2add27250e69 538 {
charly 4:2add27250e69 539 DEBUG_ENTER("C24LCXX_I2C::Read (char *): Memory address:0x%02x, readLength:%01x, Length:%d", p_address, p_readLengthFirst, p_length2write)
charly 4:2add27250e69 540
charly 4:2add27250e69 541 // 1.Prepare buffer
charly 4:2add27250e69 542 short address = p_address;
charly 4:2add27250e69 543 int length = -1;
charly 4:2add27250e69 544 if (p_readLengthFirst) { // The string was stored with its length
charly 4:2add27250e69 545 if (!Read(address, &length)) { // Read the length as integer in big endian mode
charly 4:2add27250e69 546 DEBUG_ERROR("C24LCXX_I2C::Read (char *): Failed to read length")
charly 4:2add27250e69 547 return false;
charly 4:2add27250e69 548 }
charly 4:2add27250e69 549 wait(0.02);
charly 4:2add27250e69 550 DEBUG("C24LCXX_I2C::Read (char *): length=%d", length)
charly 4:2add27250e69 551 if (length == 0) {
charly 4:2add27250e69 552 DEBUG_ERROR("C24LCXX_I2C::Read (char *): empty")
charly 4:2add27250e69 553 return true;
charly 4:2add27250e69 554 }
charly 4:2add27250e69 555 address += 4; // Skip the length value size
charly 4:2add27250e69 556 length -= 4; // length is the size of (string length + string)
charly 4:2add27250e69 557 } else { // The string length is provided by p_length2write parameter
charly 4:2add27250e69 558 if (p_length2write == -1) {
charly 4:2add27250e69 559 // read the size of buffer
charly 4:2add27250e69 560 length = strlen((const char*)p_datas);
Yann 0:21c698aa86f6 561 } else {
charly 4:2add27250e69 562 length = p_length2write;
Yann 0:21c698aa86f6 563 }
Yann 0:21c698aa86f6 564 }
charly 4:2add27250e69 565 DEBUG("C24LCXX_I2C::Read (char *): Address=0x%02x - Length=%d", address, length)
charly 4:2add27250e69 566
charly 4:2add27250e69 567 // 2. Memory address
charly 4:2add27250e69 568 char i2cBuffer[2];
charly 4:2add27250e69 569 i2cBuffer[0] = (unsigned char)(address >> 8);
charly 4:2add27250e69 570 DEBUG("C24LCXX_I2C::Read (char *): pI2CBuffer[0]: 0x%02x", i2cBuffer[0])
charly 4:2add27250e69 571 i2cBuffer[1] = (unsigned char)((unsigned char)address & 0xff);
charly 4:2add27250e69 572 DEBUG("C24LCXX_I2C::Read (char *): pI2CBuffer[1]: 0x%02x", i2cBuffer[1])
charly 4:2add27250e69 573
charly 4:2add27250e69 574 // 3. Send I2C start + memory address with repeat start
charly 4:2add27250e69 575 if (_i2cInstance->write(_slaveAddress, i2cBuffer, 2, true) == 0) {
charly 4:2add27250e69 576 wait(0.02);
charly 4:2add27250e69 577 DEBUG("C24LCXX_I2C::Read (char *): Write memory done")
charly 4:2add27250e69 578 // 4. Read data + I2C stop
charly 4:2add27250e69 579 int result = _i2cInstance->read(_slaveAddress, (char *)p_datas, length);
charly 4:2add27250e69 580
charly 4:2add27250e69 581 HEXADUMP((unsigned char *) p_datas, length);
charly 4:2add27250e69 582
charly 4:2add27250e69 583 if (result == 0) {
charly 4:2add27250e69 584 return true;
charly 4:2add27250e69 585 }
charly 4:2add27250e69 586 }
charly 4:2add27250e69 587
charly 4:2add27250e69 588 DEBUG_LEAVE("C24LCXX_I2C::Read (char *) (false)")
charly 4:2add27250e69 589 return false;
charly 4:2add27250e69 590 }
charly 4:2add27250e69 591
charly 4:2add27250e69 592
charly 4:2add27250e69 593 #if defined(__DEBUG)
charly 4:2add27250e69 594 void C24LCXX_I2C::DumpMemoryArea(const int p_address, const int p_count)
charly 4:2add27250e69 595 {
charly 4:2add27250e69 596 DEBUG_ENTER("C24LCXX_I2C::DumpMemoryArea: %d - %d", p_address, p_count)
charly 4:2add27250e69 597
charly 4:2add27250e69 598 DEBUG("C24LCXX_I2C::DumpMemoryArea: Reading datas...");
charly 4:2add27250e69 599 std::vector<unsigned char> datas(p_count);
charly 4:2add27250e69 600 if (!Read(p_address, datas, false)) { // Read bytes, including the lenght indication, buffer size is not set before the call
charly 4:2add27250e69 601 std::cout << "C24LCXX_I2C::DumpMemoryArea: read failed\r" << std::endl;
charly 4:2add27250e69 602 } else {
charly 4:2add27250e69 603 std::cout << "C24LCXX_I2C::DumpMemoryArea: Read bytes:\r" << std::endl;
charly 4:2add27250e69 604 HEXADUMP(&datas[0], p_count);
charly 4:2add27250e69 605 std::cout << "\r" << std::endl;
charly 4:2add27250e69 606 }
charly 4:2add27250e69 607 }
Yann 0:21c698aa86f6 608 #endif // _DEBUG
Yann 0:21c698aa86f6 609
Yann 0:21c698aa86f6 610 } // End of namespace _24LCXX_I2C