Subversion Repositories idreammicro-arduino

Rev

Rev 8 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7 jlesech 1
/**************************************************************************//**
2
 * \brief EEPROM 24Cxxx library for Arduino
3
 * \author Copyright (C) 2012  Julien Le Sech - www.idreammicro.com
4
 * \version 1.0
5
 * \date 20120203
6
 *
7
 * This file is part of the EEPROM 24Cxxx library for Arduino.
8
 *
9
 * This library is free software: you can redistribute it and/or modify it under
10
 * the terms of the GNU Lesser General Public License as published by the Free
11
 * Software Foundation, either version 3 of the License, or (at your option) any
12
 * later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but WITHOUT
15
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16
 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
17
 * details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program. If not, see http://www.gnu.org/licenses/
21
 ******************************************************************************/
22
 
23
/**************************************************************************//**
24
 * \file Eeprom24Cxxx.cpp
25
 ******************************************************************************/
26
 
27
/******************************************************************************
28
 * Header file inclusions.
29
 ******************************************************************************/
30
 
31
#include <Arduino.h>
32
#include <Wire.h>
33
 
34
#include <Eeprom24Cxxx.h>
35
 
36
/******************************************************************************
37
 * Private macro definitions.
38
 ******************************************************************************/
39
 
40
/**************************************************************************//**
41
 * \def EEPROM24CXXX__PAGE_SIZE
42
 * \brief Size of a page in EEPROM memory.
43
 * This size is given by EEPROM memory datasheet.
44
 ******************************************************************************/
45
#define EEPROM24CXXX__PAGE_SIZE         64
46
 
47
/**************************************************************************//**
48
 * \def EEPROM24CXXX__RD_BUFFER_SIZE
49
 * \brief Size of input TWI buffer.
50
 * This size is equal to BUFFER_LENGTH defined in Wire library (32 bytes).
51
 ******************************************************************************/
52
#define EEPROM24CXXX__RD_BUFFER_SIZE    BUFFER_LENGTH
53
 
54
/**************************************************************************//**
55
 * \def EEPROM24CXXX__WR_BUFFER_SIZE
56
 * \brief Size of output TWI buffer.
57
 * This size is equal to BUFFER_LENGTH - 2 bytes reserved for address.
58
 ******************************************************************************/
59
#define EEPROM24CXXX__WR_BUFFER_SIZE    (BUFFER_LENGTH - 2)
60
 
61
/******************************************************************************
62
 * Public method definitions.
63
 ******************************************************************************/
64
 
65
/**************************************************************************//**
66
 * \fn Eeprom24Cxxx::Eeprom24Cxxx(byte deviceAddress)
67
 *
68
 * \brief Constructor.
69
 *
70
 * \param   deviceAddress   EEPROM address on TWI bus.
71
 ******************************************************************************/
72
Eeprom24Cxxx::Eeprom24Cxxx
73
(
74
    byte deviceAddress
75
){
76
    m_deviceAddress = deviceAddress;
77
}
78
 
79
/**************************************************************************//**
80
 * \fn void Eeprom24Cxxx::initialize()
81
 *
82
 * \brief Initialize library and TWI bus.
83
 *
84
 * If several devices are connected to TWI bus, this method mustn't be
85
 * called. TWI bus must be initialized out of this library using
86
 * Wire.begin() method.
87
 ******************************************************************************/
88
void
89
Eeprom24Cxxx::initialize()
90
{
91
    Wire.begin();
92
}
93
 
94
/**************************************************************************//**
95
 * \fn void Eeprom24Cxxx::writeByte(
96
 * word address,
97
 * byte data)
98
 *
99
 * \brief Write a byte in EEPROM memory.
100
 *
101
 * \remarks A delay of 10 ms is required after write cycle.
102
 *
103
 * \param   address Address.
104
 * \param   data    Byte to write.
105
 ******************************************************************************/
106
void
107
Eeprom24Cxxx::writeByte
108
(
109
    word    address,
110
    byte    data
111
){
112
    Wire.beginTransmission(m_deviceAddress);
113
    Wire.write(address >> 8);
114
    Wire.write(address & 0xFF);
115
    Wire.write(data);
116
    Wire.endTransmission();
117
}
118
 
119
/**************************************************************************//**
120
 * \fn void Eeprom24Cxxx::writeBytes(
121
 * word     address,
122
 * word     length,
123
 * byte*    p_data)
124
 *
125
 * \brief Write bytes in EEPROM memory.
126
 *
127
 * \param       address Start address.
128
 * \param       length  Number of bytes to write.
129
 * \param[in]   p_data  Bytes to write.
130
 ******************************************************************************/
131
void
132
Eeprom24Cxxx::writeBytes
133
(
134
    word    address,
135
    word    length,
136
    byte*   p_data
137
){
138
    // Write first page if not aligned.
139
    byte notAlignedLength = 0;
140
    word pageOffset = address % EEPROM24CXXX__PAGE_SIZE;
141
    if (pageOffset > 0)
142
    {
143
        notAlignedLength = EEPROM24CXXX__PAGE_SIZE - pageOffset;
144
        writePage(address, notAlignedLength, p_data);
145
        length -= notAlignedLength;
146
    }
147
 
148
    if (length > 0)
149
    {
150
        address += notAlignedLength;
151
        p_data += notAlignedLength;
152
 
153
        // Write complete and aligned pages.
154
        word pageCount = length / EEPROM24CXXX__PAGE_SIZE;
155
        for (word i = 0; i < pageCount; i++)
156
        {
157
            writePage(address, EEPROM24CXXX__PAGE_SIZE, p_data);
158
            address += EEPROM24CXXX__PAGE_SIZE;
159
            p_data += EEPROM24CXXX__PAGE_SIZE;
160
            length -= EEPROM24CXXX__PAGE_SIZE;
161
        }
162
 
163
        if (length > 0)
164
        {
165
            // Write remaining uncomplete page.
166
            writePage(address, EEPROM24CXXX__PAGE_SIZE, p_data);
167
        }
168
    }
169
}
170
 
171
/**************************************************************************//**
172
 * \fn byte Eeprom24Cxxx::readByte(word address)
173
 *
174
 * \brief Read a byte in EEPROM memory.
175
 *
176
 * \param   address Address.
177
 *
178
 * \return Read byte.
179
 ******************************************************************************/
180
byte
181
Eeprom24Cxxx::readByte
182
(
183
    word address
184
){
185
    Wire.beginTransmission(m_deviceAddress);
186
    Wire.write(address >> 8);
187
    Wire.write(address & 0xFF);
188
    Wire.endTransmission();
189
    byte size = 1;
190
    Wire.requestFrom(m_deviceAddress, size);
191
    byte data = 0;
192
    if (Wire.available())
193
    {
194
        data = Wire.read();
195
    }
196
    return data;
197
}
198
 
199
/**************************************************************************//**
200
 * \fn void Eeprom24Cxxx::readBytes(
201
 * word     address,
202
 * word     length,
203
 * byte*    p_data)
204
 *
205
 * \brief Read bytes in EEPROM memory.
206
 *
207
 * \param       address Start address.
208
 * \param       length  Number of bytes to read.
209
 * \patam[in]   p_data  Byte array to fill with read bytes.
210
 ******************************************************************************/
211
void
212
Eeprom24Cxxx::readBytes
213
(
214
    word    address,
215
    word    length,
216
    byte*   p_data
217
){
218
    byte bufferCount = length / EEPROM24CXXX__RD_BUFFER_SIZE;
219
    for (byte i = 0; i < bufferCount; i++)
220
    {
221
        word offset = i * EEPROM24CXXX__RD_BUFFER_SIZE;
222
        readBuffer(address + offset, EEPROM24CXXX__RD_BUFFER_SIZE, p_data + offset);
223
    }
224
 
225
    byte remainingBytes = length % EEPROM24CXXX__RD_BUFFER_SIZE;
226
    word offset = length - remainingBytes;
227
    readBuffer(address + offset, remainingBytes, p_data + offset);
228
}
229
 
230
/******************************************************************************
231
 * Private method definitions.
232
 ******************************************************************************/
233
 
234
/**************************************************************************//**
235
 * \fn void Eeprom24Cxxx::writePage(
236
 * word     address,
237
 * byte     length,
238
 * byte*    p_data)
239
 *
240
 * \brief Write page in EEPROM memory.
241
 *
242
 * \param       address Start address.
243
 * \param       length  Number of bytes (EEPROM24CXXX__PAGE_SIZE bytes max).
244
 * \param[in]   p_data  Data.
245
 ******************************************************************************/
246
void
247
Eeprom24Cxxx::writePage
248
(
249
    word    address,
250
    byte    length,
251
    byte*   p_data
252
){
253
    // Write complete buffers.
254
    byte bufferCount = length / EEPROM24CXXX__WR_BUFFER_SIZE;
255
    for (byte i = 0; i < bufferCount; i++)
256
    {
257
        word offset = i * EEPROM24CXXX__WR_BUFFER_SIZE;
258
        writeBuffer(address + offset, EEPROM24CXXX__WR_BUFFER_SIZE, p_data + offset);
259
    }
260
 
261
    // Write remaining bytes.
262
    byte remainingBytes = length % EEPROM24CXXX__WR_BUFFER_SIZE;
263
    word offset = length - remainingBytes;
264
    writeBuffer(address + offset, remainingBytes, p_data + offset);
265
}
266
 
267
/**************************************************************************//**
268
 * \fn void Eeprom24Cxxx::writeBuffer(
269
 * word     address,
270
 * byte     length,
271
 * byte*    p_data)
272
 *
273
 * \brief Write bytes into memory.
274
 *
275
 * \param       address Start address.
276
 * \param       length  Number of bytes (EEPROM24CXXX__WR_BUFFER_SIZE bytes max).
277
 * \param[in]   p_data  Data.
278
 ******************************************************************************/
279
void
280
Eeprom24Cxxx::writeBuffer
281
(
282
    word    address,
283
    byte    length,
284
    byte*   p_data
285
){
286
    Wire.beginTransmission(m_deviceAddress);
287
    Wire.write(address >> 8);
288
    Wire.write(address & 0xFF);
289
    for (byte i = 0; i < length; i++)
290
    {
291
        Wire.write(p_data[i]);
292
    }
293
    Wire.endTransmission();
294
 
295
    // Write cycle time (tWR). See EEPROM memory datasheet for more details.
296
    delay(10);
297
}
298
 
299
/**************************************************************************//**
300
 * \fn void Eeprom24Cxxx::readBuffer(
301
 * word     address,
302
 * byte     length,
303
 * byte*    p_data)
304
 *
305
 * \brief Read bytes in memory.
306
 *
307
 * \param       address Start address.
308
 * \param       length  Number of bytes (EEPROM24CXXX__RD_BUFFER_SIZE bytes max).
309
 * \param[in]   p_data  Buffer to fill with read bytes.
310
 ******************************************************************************/
311
void
312
Eeprom24Cxxx::readBuffer
313
(
314
    word    address,
315
    byte    length,
316
    byte*   p_data
317
){
318
    Wire.beginTransmission(m_deviceAddress);
319
    Wire.write(address >> 8);
320
    Wire.write(address & 0xFF);
321
    Wire.endTransmission();
322
    Wire.requestFrom(m_deviceAddress, length);
323
    for (byte i = 0; i < length; i++)
324
    {
325
        if (Wire.available())
326
        {
327
            p_data[i] = Wire.read();
328
        }
329
    }
330
}
331