Subversion Repositories idreammicro-arduino

Rev

Rev 16 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
16 jlesech 1
/**************************************************************************//**
2
 * \brief EEPROM 24C512 library for Arduino
3
 * \author Copyright (C) 2012  Julien Le Sech - www.idreammicro.com
4
 * \version 1.0
5
 * \date 20120218
6
 *
7
 * This file is part of the EEPROM 24C512 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 Eeprom24C512.cpp
25
 ******************************************************************************/
26
 
27
/******************************************************************************
28
 * Header file inclusions.
29
 ******************************************************************************/
30
 
31
#include <Arduino.h>
32
#include <Wire.h>
33
 
34
#include <Eeprom24C512.h>
35
 
36
/******************************************************************************
37
 * Private macro definitions.
38
 ******************************************************************************/
39
 
40
/**************************************************************************//**
41
 * \def EEPROM__PAGE_SIZE
42
 * \brief Size of a page in EEPROM memory.
43
 * This size is given by EEPROM memory datasheet.
44
 ******************************************************************************/
45
#define EEPROM__PAGE_SIZE         128
46
 
47
/**************************************************************************//**
48
 * \def EEPROM__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 EEPROM__RD_BUFFER_SIZE    BUFFER_LENGTH
53
 
54
/**************************************************************************//**
55
 * \def EEPROM__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 EEPROM__WR_BUFFER_SIZE    (BUFFER_LENGTH - 2)
60
 
61
/******************************************************************************
62
 * Public method definitions.
63
 ******************************************************************************/
64
 
65
/**************************************************************************//**
66
 * \fn Eeprom24C512::Eeprom24C512(byte deviceAddress)
67
 *
68
 * \brief Constructor.
69
 *
70
 * \param   deviceAddress   EEPROM address on TWI bus.
71
 ******************************************************************************/
72
Eeprom24C512::Eeprom24C512
73
(
74
    byte deviceAddress
75
){
76
    m_deviceAddress = deviceAddress;
77
}
78
 
79
/**************************************************************************//**
80
 * \fn void Eeprom24C512::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
Eeprom24C512::initialize()
90
{
91
    Wire.begin();
92
}
93
 
94
/**************************************************************************//**
95
 * \fn void Eeprom24C512::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
Eeprom24C512::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 Eeprom24C512::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
Eeprom24C512::writeBytes
133
(
134
    word    address,
135
    word    length,
136
    byte*   p_data
137
){
138
    // Write first page if not aligned.
139
    byte notAlignedLength = 0;
20 jlesech 140
    byte pageOffset = address % EEPROM__PAGE_SIZE;
16 jlesech 141
    if (pageOffset > 0)
142
    {
143
        notAlignedLength = EEPROM__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 / EEPROM__PAGE_SIZE;
155
        for (word i = 0; i < pageCount; i++)
156
        {
157
            writePage(address, EEPROM__PAGE_SIZE, p_data);
158
            address += EEPROM__PAGE_SIZE;
159
            p_data += EEPROM__PAGE_SIZE;
160
            length -= EEPROM__PAGE_SIZE;
161
        }
162
 
163
        if (length > 0)
164
        {
165
            // Write remaining uncomplete page.
166
            writePage(address, EEPROM__PAGE_SIZE, p_data);
167
        }
168
    }
169
}
170
 
171
/**************************************************************************//**
172
 * \fn byte Eeprom24C512::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
Eeprom24C512::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
    Wire.requestFrom(m_deviceAddress, (byte)1);
190
    byte data = 0;
191
    if (Wire.available())
192
    {
193
        data = Wire.read();
194
    }
195
    return data;
196
}
197
 
198
/**************************************************************************//**
199
 * \fn void Eeprom24C512::readBytes(
200
 * word     address,
201
 * word     length,
202
 * byte*    p_data)
203
 *
204
 * \brief Read bytes in EEPROM memory.
205
 *
206
 * \param       address Start address.
207
 * \param       length  Number of bytes to read.
208
 * \patam[in]   p_data  Byte array to fill with read bytes.
209
 ******************************************************************************/
210
void
211
Eeprom24C512::readBytes
212
(
213
    word    address,
214
    word    length,
215
    byte*   p_data
216
){
20 jlesech 217
    word bufferCount = length / EEPROM__RD_BUFFER_SIZE;
218
    for (word i = 0; i < bufferCount; i++)
16 jlesech 219
    {
220
        word offset = i * EEPROM__RD_BUFFER_SIZE;
221
        readBuffer(address + offset, EEPROM__RD_BUFFER_SIZE, p_data + offset);
222
    }
223
 
224
    byte remainingBytes = length % EEPROM__RD_BUFFER_SIZE;
225
    word offset = length - remainingBytes;
226
    readBuffer(address + offset, remainingBytes, p_data + offset);
227
}
228
 
229
/******************************************************************************
230
 * Private method definitions.
231
 ******************************************************************************/
232
 
233
/**************************************************************************//**
234
 * \fn void Eeprom24C512::writePage(
235
 * word     address,
236
 * byte     length,
237
 * byte*    p_data)
238
 *
239
 * \brief Write page in EEPROM memory.
240
 *
241
 * \param       address Start address.
242
 * \param       length  Number of bytes (EEPROM__PAGE_SIZE bytes max).
243
 * \param[in]   p_data  Data.
244
 ******************************************************************************/
245
void
246
Eeprom24C512::writePage
247
(
248
    word    address,
249
    byte    length,
250
    byte*   p_data
251
){
252
    // Write complete buffers.
253
    byte bufferCount = length / EEPROM__WR_BUFFER_SIZE;
254
    for (byte i = 0; i < bufferCount; i++)
255
    {
20 jlesech 256
        byte offset = i * EEPROM__WR_BUFFER_SIZE;
16 jlesech 257
        writeBuffer(address + offset, EEPROM__WR_BUFFER_SIZE, p_data + offset);
258
    }
259
 
260
    // Write remaining bytes.
261
    byte remainingBytes = length % EEPROM__WR_BUFFER_SIZE;
20 jlesech 262
    byte offset = length - remainingBytes;
16 jlesech 263
    writeBuffer(address + offset, remainingBytes, p_data + offset);
264
}
265
 
266
/**************************************************************************//**
267
 * \fn void Eeprom24C512::writeBuffer(
268
 * word     address,
269
 * byte     length,
270
 * byte*    p_data)
271
 *
272
 * \brief Write bytes into memory.
273
 *
274
 * \param       address Start address.
275
 * \param       length  Number of bytes (EEPROM__WR_BUFFER_SIZE bytes max).
276
 * \param[in]   p_data  Data.
277
 ******************************************************************************/
278
void
279
Eeprom24C512::writeBuffer
280
(
281
    word    address,
282
    byte    length,
283
    byte*   p_data
284
){
285
    Wire.beginTransmission(m_deviceAddress);
286
    Wire.write(address >> 8);
287
    Wire.write(address & 0xFF);
288
    for (byte i = 0; i < length; i++)
289
    {
290
        Wire.write(p_data[i]);
291
    }
292
    Wire.endTransmission();
293
 
294
    // Write cycle time (tWR). See EEPROM memory datasheet for more details.
295
    delay(10);
296
}
297
 
298
/**************************************************************************//**
299
 * \fn void Eeprom24C512::readBuffer(
300
 * word     address,
301
 * byte     length,
302
 * byte*    p_data)
303
 *
304
 * \brief Read bytes in memory.
305
 *
306
 * \param       address Start address.
307
 * \param       length  Number of bytes (EEPROM__RD_BUFFER_SIZE bytes max).
308
 * \param[in]   p_data  Buffer to fill with read bytes.
309
 ******************************************************************************/
310
void
311
Eeprom24C512::readBuffer
312
(
313
    word    address,
314
    byte    length,
315
    byte*   p_data
316
){
317
    Wire.beginTransmission(m_deviceAddress);
318
    Wire.write(address >> 8);
319
    Wire.write(address & 0xFF);
320
    Wire.endTransmission();
321
    Wire.requestFrom(m_deviceAddress, length);
322
    for (byte i = 0; i < length; i++)
323
    {
324
        if (Wire.available())
325
        {
326
            p_data[i] = Wire.read();
327
        }
328
    }
329
}
330