Subversion Repositories idreammicro-arduino

Rev

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

Rev Author Line No. Line
14 jlesech 1
/**************************************************************************//**
2
 * \brief EEPROM 24C04 / 24C16 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 24C04 / 24C16 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 Eeprom24C04_16.cpp
25
 ******************************************************************************/
26
 
27
/******************************************************************************
28
 * Header file inclusions.
29
 ******************************************************************************/
30
 
31
#include <Arduino.h>
32
#include <Wire.h>
33
 
34
#include <Eeprom24C04_16.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         16
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 - 1 byte reserved for address.
58
 ******************************************************************************/
59
#define EEPROM__WR_BUFFER_SIZE    (BUFFER_LENGTH - 1)
60
 
61
/******************************************************************************
62
 * Public method definitions.
63
 ******************************************************************************/
64
 
65
/**************************************************************************//**
66
 * \fn Eeprom24C04_16::Eeprom24C04_16(byte deviceAddress)
67
 *
68
 * \brief Constructor.
69
 *
70
 * \param   deviceAddress   EEPROM address on TWI bus.
71
 ******************************************************************************/
72
Eeprom24C04_16::Eeprom24C04_16
73
(
74
    byte deviceAddress
75
){
76
    m_deviceAddress = deviceAddress;
77
}
78
 
79
/**************************************************************************//**
80
 * \fn void Eeprom24C04_16::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
Eeprom24C04_16::initialize()
90
{
91
    Wire.begin();
92
}
93
 
94
/**************************************************************************//**
95
 * \fn void Eeprom24C04_16::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
Eeprom24C04_16::writeByte
108
(
109
    word    address,
110
    byte    data
111
){
112
    Wire.beginTransmission((byte)(m_deviceAddress | ((address >> 8) & 0x07)));
113
    Wire.write(address & 0xFF);
114
    Wire.write(data);
115
    Wire.endTransmission();
116
}
117
 
118
/**************************************************************************//**
119
 * \fn void Eeprom24C04_16::writeBytes(
120
 * word     address,
121
 * word     length,
122
 * byte*    p_data)
123
 *
124
 * \brief Write bytes in EEPROM memory.
125
 *
126
 * \param       address Start address.
127
 * \param       length  Number of bytes to write.
128
 * \param[in]   p_data  Bytes to write.
129
 ******************************************************************************/
130
void
131
Eeprom24C04_16::writeBytes
132
(
133
    word    address,
134
    word    length,
135
    byte*   p_data
136
){
137
    // Write first page if not aligned.
138
    byte notAlignedLength = 0;
17 jlesech 139
    byte pageOffset = address % EEPROM__PAGE_SIZE;
14 jlesech 140
    if (pageOffset > 0)
141
    {
142
        notAlignedLength = EEPROM__PAGE_SIZE - pageOffset;
143
        writePage(address, notAlignedLength, p_data);
144
        length -= notAlignedLength;
145
    }
146
 
147
    if (length > 0)
148
    {
149
        address += notAlignedLength;
150
        p_data += notAlignedLength;
151
 
152
        // Write complete and aligned pages.
17 jlesech 153
        byte pageCount = length / EEPROM__PAGE_SIZE;
154
        for (byte i = 0; i < pageCount; i++)
14 jlesech 155
        {
156
            writePage(address, EEPROM__PAGE_SIZE, p_data);
157
            address += EEPROM__PAGE_SIZE;
158
            p_data += EEPROM__PAGE_SIZE;
159
            length -= EEPROM__PAGE_SIZE;
160
        }
161
 
162
        if (length > 0)
163
        {
164
            // Write remaining uncomplete page.
165
            writePage(address, EEPROM__PAGE_SIZE, p_data);
166
        }
167
    }
168
}
169
 
170
/**************************************************************************//**
171
 * \fn byte Eeprom24C04_16::readByte(word address)
172
 *
173
 * \brief Read a byte in EEPROM memory.
174
 *
175
 * \param   address Address.
176
 *
177
 * \return Read byte.
178
 ******************************************************************************/
179
byte
180
Eeprom24C04_16::readByte
181
(
182
    word address
183
){
184
    Wire.beginTransmission((byte)(m_deviceAddress | ((address >> 8) & 0x07)));
185
    Wire.write(address & 0xFF);
186
    Wire.endTransmission();
187
    Wire.requestFrom((byte)(m_deviceAddress | ((address >> 8) & 0x07)), (byte)1);
188
    byte data = 0;
189
    if (Wire.available())
190
    {
191
        data = Wire.read();
192
    }
193
    return data;
194
}
195
 
196
/**************************************************************************//**
197
 * \fn void Eeprom24C04_16::readBytes(
198
 * word     address,
199
 * word     length,
200
 * byte*    p_data)
201
 *
202
 * \brief Read bytes in EEPROM memory.
203
 *
204
 * \param       address Start address.
205
 * \param       length  Number of bytes to read.
206
 * \patam[in]   p_data  Byte array to fill with read bytes.
207
 ******************************************************************************/
208
void
209
Eeprom24C04_16::readBytes
210
(
211
    word    address,
212
    word    length,
213
    byte*   p_data
214
){
215
    byte bufferCount = length / EEPROM__RD_BUFFER_SIZE;
216
    for (byte i = 0; i < bufferCount; i++)
217
    {
218
        word offset = i * EEPROM__RD_BUFFER_SIZE;
219
        readBuffer(address + offset, EEPROM__RD_BUFFER_SIZE, p_data + offset);
220
    }
221
 
222
    byte remainingBytes = length % EEPROM__RD_BUFFER_SIZE;
223
    word offset = length - remainingBytes;
224
    readBuffer(address + offset, remainingBytes, p_data + offset);
225
}
226
 
227
/******************************************************************************
228
 * Private method definitions.
229
 ******************************************************************************/
230
 
231
/**************************************************************************//**
232
 * \fn void Eeprom24C04_16::writePage(
233
 * word     address,
234
 * byte     length,
235
 * byte*    p_data)
236
 *
237
 * \brief Write page in EEPROM memory.
238
 *
239
 * \param       address Start address.
240
 * \param       length  Number of bytes (EEPROM__PAGE_SIZE bytes max).
241
 * \param[in]   p_data  Data.
242
 ******************************************************************************/
243
void
244
Eeprom24C04_16::writePage
245
(
246
    word    address,
247
    byte    length,
248
    byte*   p_data
249
){
250
    // Write complete buffers.
251
    byte bufferCount = length / EEPROM__WR_BUFFER_SIZE;
252
    for (byte i = 0; i < bufferCount; i++)
253
    {
17 jlesech 254
        byte offset = i * EEPROM__WR_BUFFER_SIZE;
14 jlesech 255
        writeBuffer(address + offset, EEPROM__WR_BUFFER_SIZE, p_data + offset);
256
    }
257
 
258
    // Write remaining bytes.
259
    byte remainingBytes = length % EEPROM__WR_BUFFER_SIZE;
17 jlesech 260
    byte offset = length - remainingBytes;
14 jlesech 261
    writeBuffer(address + offset, remainingBytes, p_data + offset);
262
}
263
 
264
/**************************************************************************//**
265
 * \fn void Eeprom24C04_16::writeBuffer(
266
 * word     address,
267
 * byte     length,
268
 * byte*    p_data)
269
 *
270
 * \brief Write bytes into memory.
271
 *
272
 * \param       address Start address.
273
 * \param       length  Number of bytes (EEPROM__WR_BUFFER_SIZE bytes max).
274
 * \param[in]   p_data  Data.
275
 ******************************************************************************/
276
void
277
Eeprom24C04_16::writeBuffer
278
(
279
    word    address,
280
    byte    length,
281
    byte*   p_data
282
){
283
    Wire.beginTransmission((byte)(m_deviceAddress | ((address >> 8) & 0x07)));
284
    Wire.write(address & 0xFF);
285
    for (byte i = 0; i < length; i++)
286
    {
287
        Wire.write(p_data[i]);
288
    }
289
    Wire.endTransmission();
290
 
291
    // Write cycle time (tWR). See EEPROM memory datasheet for more details.
292
    delay(10);
293
}
294
 
295
/**************************************************************************//**
296
 * \fn void Eeprom24C04_16::readBuffer(
297
 * word     address,
298
 * byte     length,
299
 * byte*    p_data)
300
 *
301
 * \brief Read bytes in memory.
302
 *
303
 * \param       address Start address.
304
 * \param       length  Number of bytes (EEPROM__RD_BUFFER_SIZE bytes max).
305
 * \param[in]   p_data  Buffer to fill with read bytes.
306
 ******************************************************************************/
307
void
308
Eeprom24C04_16::readBuffer
309
(
310
    word    address,
311
    byte    length,
312
    byte*   p_data
313
){
314
    Wire.beginTransmission((byte)(m_deviceAddress | ((address >> 8) & 0x07)));
315
    Wire.write(address & 0xFF);
316
    Wire.endTransmission();
317
    Wire.requestFrom((byte)(m_deviceAddress | ((address >> 8) & 0x07)), length);
318
    for (byte i = 0; i < length; i++)
319
    {
320
        if (Wire.available())
321
        {
322
            p_data[i] = Wire.read();
323
        }
324
    }
325
}