OpenCores
URL https://opencores.org/ocsvn/xenie/xenie/trunk

Subversion Repositories xenie

[/] [xenie/] [trunk/] [examples/] [Eth_example/] [mb_fw/] [drivers/] [iic_v3_4/] [examples/] [xiic_low_level_eeprom_example.c] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 DFC
/******************************************************************************
2
*
3
* Copyright (C) 2002 - 2014 Xilinx, Inc.  All rights reserved.
4
*
5
* Permission is hereby granted, free of charge, to any person obtaining a copy
6
* of this software and associated documentation files (the "Software"), to deal
7
* in the Software without restriction, including without limitation the rights
8
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
* copies of the Software, and to permit persons to whom the Software is
10
* furnished to do so, subject to the following conditions:
11
*
12
* The above copyright notice and this permission notice shall be included in
13
* all copies or substantial portions of the Software.
14
*
15
* Use of the Software is limited solely to applications:
16
* (a) running on a Xilinx device, or
17
* (b) that interact with a Xilinx device through a bus or interconnect.
18
*
19
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22
* XILINX  BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
* SOFTWARE.
26
*
27
* Except as contained in this notice, the name of the Xilinx shall not be used
28
* in advertising or otherwise to promote the sale, use or other dealings in
29
* this Software without prior written authorization from Xilinx.
30
*
31
******************************************************************************/
32
/*****************************************************************************/
33
/**
34
* @file xiic_low_level_eeprom_example.c
35
*
36
* This file consists of a polled mode design example which uses the Xilinx
37
* IIC device and low-level driver to exercise the EEPROM.
38
*
39
* This example writes/reads from the lower 256 bytes of the IIC EEPROMS. Please
40
* refer to the datasheets of the IIC EEPROM's for details about the internal
41
* addressing and page size of these devices.
42
*
43
* The XIic_Send() API is used to transmit the data and XIic_Recv() API is used
44
* to receive the data.
45
*
46
* This example is tested on ML300/ML310/ML403/ML501/ML507/ML510/ML605/SP601 and
47
* SP605 Xilinx boards.
48
*
49
* The ML310/ML410/ML510 boards have a on-board 64 Kb serial IIC EEPROM
50
* (Microchip 24LC64A). The WP pin of the IIC EEPROM is hardwired to ground on
51
* this board.
52
*
53
* The ML300 board has an on-board 32 Kb serial IIC EEPROM(Microchip 24LC32A).
54
* The WP pin of the IIC EEPROM has to be connected to ground for this example.
55
* The WP is connected to pin Y3 of the FPGA.
56
*
57
* The ML403 board has an on-board 4 Kb serial IIC EEPROM(Microchip 24LC04A).
58
* The WP pin of the IIC EEPROM is hardwired to ground on this board.
59
*
60
* The ML501/ML505/ML507/ML605/SP601/SP605 boards have an on-board 8 Kb serial
61
* IIC EEPROM(STM M24C08). The WP pin of the IIC EEPROM is hardwired to
62
* ground on these boards.
63
*
64
* The AddressType for ML300/ML310/ML410/ML510 boards should be u16 as the
65
* address pointer in the on board EEPROM is 2 bytes.
66
*
67
* The AddressType for ML403/ML501/ML505/ML507/ML605/SP601/SP605 boards should
68
* be u8 as the address pointer for the on board EEPROM is 1 byte.
69
*
70
* The 7 bit IIC Slave address of the IIC EEPROM on the ML300/ML310/ML403/ML410/
71
* ML501/ML505/ML507/ML510 boards is 0x50.
72
* The 7 bit IIC Slave address of the IIC EEPROM on the ML605/SP601/SP605 boards
73
* is 0x54.
74
* Refer to the User Guide's of the respective boards for further information
75
* about the IIC slave address of IIC EEPROM's.
76
*
77
* The define EEPROM_ADDRESS in this file needs to be changed depending on
78
* the board on which this example is to be run.
79
*
80
* This code assumes that no Operating System is being used.
81
*
82
* @note         None
83
*
84
* <pre>
85
* MODIFICATION HISTORY:
86
*
87
* Ver   Who  Date        Changes
88
* ----- ---- -------- -----------------------------------------------
89
* 1.00a jhl  09/10/03 Created
90
* 1.00a sv   05/09/05 Minor changes to comply to Doxygen and coding guidelines
91
* 1.00a mta  03/09/06 Minor updates due to changes in the low level driver for
92
*                     supporting repeated start functionality.
93
* 2.00a sdm  09/22/09 Converted all register accesses to 32 bit access and minor
94
*                     modifications as per coding guidelines.
95
* 2.01a ktn  03/17/10 Updated the information about the EEPROM's used on
96
*                     ML605/SP601/SP605 boards. Updated the example so that it
97
*                     can be used to access the entire IIC EEPROM for devices
98
*                     like M24C04/M24C08 that use LSB bits of the IIC device
99
*                     select code (IIC slave address) to specify the higher
100
*                     address bits of the EEPROM internal address.
101
* 2.01a sdm  06/13/11 Updated the example to flush the Tx FIFO when waiting for
102
*                     the previous command to be completed for CR612546.
103
* </pre>
104
*
105
******************************************************************************/
106
 
107
/***************************** Include Files *********************************/
108
 
109
#include "xparameters.h"
110
#include "xiic.h"
111
#include "xil_io.h"
112
 
113
/************************** Constant Definitions *****************************/
114
 
115
/*
116
 * The following constants map to the XPAR parameters created in the
117
 * xparameters.h file. They are defined here such that a user can easily
118
 * change all the needed parameters in one place.
119
 */
120
#define IIC_BASE_ADDRESS        XPAR_IIC_0_BASEADDR
121
 
122
/*
123
 * The following constant defines the address of the IIC Slave device on the
124
 * IIC bus. Note that since the address is only 7 bits, this constant is the
125
 * address divided by 2.
126
 * The 7 bit IIC Slave address of the IIC EEPROM on the ML300/ML310/ML403/ML410/
127
 * ML501/ML505/ML507/ML510 boards is 0x50. The 7 bit IIC Slave address of the
128
 * IIC EEPROM on the ML605/SP601/SP605 boards is 0x54.
129
 * Please refer the User Guide's of the respective boards for further
130
 * information about the IIC slave address of IIC EEPROM's.
131
 */
132
#define EEPROM_ADDRESS  0x54     /* 0xA0 as an 8 bit number */
133
 
134
/*
135
 * The page size determines how much data should be written at a time.
136
 * The ML300 board supports a page size of 32 and 16
137
 * The write function should be called with this as a maximum byte count.
138
 */
139
#define PAGE_SIZE       16
140
 
141
/*
142
 * The Starting address in the IIC EEPROM on which this test is performed
143
 */
144
#define EEPROM_TEST_START_ADDRESS       128
145
 
146
 
147
/**************************** Type Definitions *******************************/
148
 
149
/*
150
 * The AddressType for ML300/ML310/ML510 boards should be u16 as the address
151
 * pointer in the on board EEPROM is 2 bytes.
152
 * The AddressType for ML403/ML501/ML505/ML507/ML605/SP601/SP605 boards should
153
 * be u8 as the address pointer in the on board EEPROM is 1 bytes.
154
 */
155
typedef u8 AddressType;
156
 
157
 
158
/***************** Macros (Inline Functions) Definitions *********************/
159
 
160
 
161
/************************** Function Prototypes ******************************/
162
 
163
int IicLowLevelEeprom();
164
 
165
int ReadWriteVerify(AddressType Address);
166
 
167
unsigned EepromWriteByte(AddressType Address, u8 *BufferPtr, u16 ByteCount);
168
 
169
unsigned EepromReadByte(AddressType Address, u8 *BufferPtr, u16 ByteCount);
170
 
171
/************************** Variable Definitions **************************/
172
 
173
int ErrorCount;                   /* The Error Count */
174
 
175
u8 WriteBuffer[PAGE_SIZE];        /* Write buffer for writing a page */
176
u8 ReadBuffer[PAGE_SIZE];         /* Read buffer for reading a page */
177
u8 ReadBufferAll[PAGE_SIZE * 4];  /* Buffer used for reading all the data */
178
 
179
u8 EepromIicAddr;                 /* Variable for storing Eeprom IIC address */
180
 
181
/*****************************************************************************/
182
/**
183
* Main function to call the low level EEPROM example.
184
*
185
* @param        None.
186
*
187
* @return       XST_SUCCESS if successful, XST_FAILURE if unsuccessful.
188
*
189
* @note         None.
190
*
191
******************************************************************************/
192
int main(void)
193
{
194
        int Status;
195
 
196
        /*
197
         * Run the Low Level EEPROM example.
198
         */
199
        Status = IicLowLevelEeprom();
200
        if (Status != XST_SUCCESS) {
201
                return XST_FAILURE;
202
        }
203
 
204
        return XST_SUCCESS;
205
}
206
 
207
/*****************************************************************************/
208
/**
209
* The function uses the low level driver of IIC to read and write to the
210
* IIC EEPROM board. The addresses tested are from 128 to 192.
211
*
212
* @param        None.
213
*
214
* @return       XST_SUCCESS if successful, XST_FAILURE if unsuccessful.
215
*
216
* @note         None.
217
*
218
****************************************************************************/
219
int IicLowLevelEeprom()
220
{
221
        int Status;
222
        unsigned BytesRead;
223
        EepromIicAddr = EEPROM_ADDRESS;
224
 
225
        /*
226
         * Read, write and verify a page of data at the specified address.
227
         */
228
        Status = ReadWriteVerify(EEPROM_TEST_START_ADDRESS);
229
        if (Status != XST_SUCCESS) {
230
                ErrorCount++;
231
        }
232
 
233
        /*
234
         * Read, write and verify a page of data at the
235
         * specified address + PAGE_SIZE.
236
         */
237
        Status = ReadWriteVerify(EEPROM_TEST_START_ADDRESS + PAGE_SIZE);
238
        if (Status != XST_SUCCESS) {
239
                ErrorCount++;
240
        }
241
 
242
        /*
243
         * Read, write and verify a page of data at the
244
         * specified address + (PAGE_SIZE * 3).
245
         */
246
        Status = ReadWriteVerify(EEPROM_TEST_START_ADDRESS + (PAGE_SIZE * 3));
247
        if (Status != XST_SUCCESS) {
248
                ErrorCount++;
249
        }
250
 
251
        /*
252
         * Read, write and verify a page of data at the
253
         * specified address + (PAGE_SIZE * 2).
254
         */
255
        Status = ReadWriteVerify(EEPROM_TEST_START_ADDRESS + (PAGE_SIZE * 2));
256
        if (Status != XST_SUCCESS) {
257
                ErrorCount++;
258
        }
259
 
260
        /*
261
         * Read all the locations that were written in a single read,
262
         * this data is not verified, only read to show that a larger
263
         * amount of data can be read.
264
        */
265
        BytesRead = EepromReadByte(EEPROM_TEST_START_ADDRESS,
266
                                        ReadBufferAll,
267
                                        PAGE_SIZE * 4);
268
        if (BytesRead != PAGE_SIZE * 4) {
269
                ErrorCount++;
270
        }
271
 
272
        if (ErrorCount != 0x0) {
273
                Status = XST_FAILURE;
274
        } else {
275
                Status = XST_SUCCESS;
276
        }
277
 
278
        return Status;
279
}
280
 
281
/*****************************************************************************/
282
/**
283
* This function writes, reads, and verifies the read to the IIC EEPROM.  It
284
* does the write as a single page write, performs a buffered read, and also
285
* performs byte reads.
286
*
287
* @param        Address is the starting address of the page in the EEPROM device
288
*               to which the data is to be written.
289
*
290
* @return        XST_FAILURE if the test fails, XST_SUCCESS if the test passes.
291
*
292
* @note         None.
293
*
294
****************************************************************************/
295
int ReadWriteVerify(AddressType Address)
296
{
297
        unsigned BytesWritten;
298
        unsigned BytesRead;
299
        int Index;
300
 
301
        /*
302
         * Initialize the data to written and the read buffer.
303
         */
304
        for (Index = 0; Index < PAGE_SIZE; Index++) {
305
                WriteBuffer[Index] = Index;
306
                ReadBuffer[Index] = 0;
307
        }
308
 
309
        /*
310
         * Write to the EEPROM.
311
         */
312
        BytesWritten = EepromWriteByte(Address, WriteBuffer, PAGE_SIZE);
313
        if (BytesWritten != PAGE_SIZE) {
314
                return XST_FAILURE;
315
        }
316
 
317
        /*
318
         * Read from the EEPROM.
319
         */
320
        BytesRead = EepromReadByte(Address, ReadBuffer, PAGE_SIZE);
321
        if (BytesRead != PAGE_SIZE) {
322
                return XST_FAILURE;
323
        }
324
 
325
        /*
326
         * Verify the data read against the data written.
327
         */
328
        for (Index = 0; Index < PAGE_SIZE; Index++)
329
        {
330
                if (ReadBuffer[Index] != WriteBuffer[Index]) {
331
                        return XST_FAILURE;
332
                }
333
                ReadBuffer[Index] = 0;
334
        }
335
 
336
        /*
337
         * Read each byte one at a time and verify.
338
         */
339
        for (Index = 0; Index < PAGE_SIZE; Index++)
340
        {
341
                BytesRead = EepromReadByte(Address + Index,
342
                                &ReadBuffer[Index], 1);
343
                if (BytesRead != 1) {
344
                        return XST_FAILURE;
345
                }
346
 
347
                if (ReadBuffer[Index] != WriteBuffer[Index]) {
348
                        return XST_FAILURE;
349
                }
350
        }
351
 
352
        return XST_SUCCESS;
353
}
354
 
355
/*****************************************************************************/
356
/**
357
* This function writes a buffer of bytes to the IIC serial EEPROM.
358
*
359
* @param        Address contains the address in the EEPROM to write to.
360
* @param        BufferPtr contains the address of the data to write.
361
* @param        ByteCount contains the number of bytes in the buffer to be written.
362
*               Note that this should not exceed the page size of the EEPROM as
363
*               noted by the constant PAGE_SIZE.
364
*
365
* @return       The number of bytes written, a value less than that which was
366
*               specified as an input indicates an error.
367
*
368
* @note         None.
369
*
370
****************************************************************************/
371
unsigned EepromWriteByte(AddressType Address, u8 *BufferPtr, u16 ByteCount)
372
{
373
        volatile unsigned SentByteCount;
374
        volatile unsigned AckByteCount;
375
        u8 WriteBuffer[sizeof(Address) + PAGE_SIZE];
376
        int Index;
377
 
378
 
379
        /*
380
         * A temporary write buffer must be used which contains both the address
381
         * and the data to be written, put the address in first based upon the
382
         * size of the address for the EEPROM.
383
         */
384
        if (sizeof(AddressType) == 2) {
385
                WriteBuffer[0] = (u8)(Address >> 8);
386
                WriteBuffer[1] = (u8)(Address);
387
        } else if (sizeof(AddressType) == 1) {
388
                WriteBuffer[0] = (u8)(Address);
389
                EepromIicAddr |= (EEPROM_TEST_START_ADDRESS >> 8) & 0x7;
390
        }
391
 
392
        /*
393
         * Put the data in the write buffer following the address.
394
         */
395
        for (Index = 0; Index < ByteCount; Index++) {
396
                WriteBuffer[sizeof(Address) + Index] = BufferPtr[Index];
397
        }
398
 
399
        /*
400
         * Set the address register to the specified address by writing
401
         * the address to the device, this must be tried until it succeeds
402
         * because a previous write to the device could be pending and it
403
         * will not ack until that write is complete.
404
         */
405
        do {
406
                SentByteCount = XIic_Send(IIC_BASE_ADDRESS,
407
                                        EepromIicAddr,
408
                                        (u8 *)&Address, sizeof(Address),
409
                                        XIIC_STOP);
410
                if (SentByteCount != sizeof(Address)) {
411
 
412
                        /* Send is aborted so reset Tx FIFO */
413
                        XIic_WriteReg(IIC_BASE_ADDRESS,  XIIC_CR_REG_OFFSET,
414
                                        XIIC_CR_TX_FIFO_RESET_MASK);
415
                        XIic_WriteReg(IIC_BASE_ADDRESS, XIIC_CR_REG_OFFSET,
416
                                        XIIC_CR_ENABLE_DEVICE_MASK);
417
                }
418
 
419
        } while (SentByteCount != sizeof(Address));
420
 
421
        /*
422
         * Write a page of data at the specified address to the EEPROM.
423
         */
424
        SentByteCount = XIic_Send(IIC_BASE_ADDRESS, EepromIicAddr,
425
                                  WriteBuffer, sizeof(Address) + PAGE_SIZE,
426
                                  XIIC_STOP);
427
 
428
        /*
429
         * Wait for the write to be complete by trying to do a write and
430
         * the device will not ack if the write is still active.
431
         */
432
        do {
433
                AckByteCount = XIic_Send(IIC_BASE_ADDRESS, EepromIicAddr,
434
                                        (u8 *)&Address, sizeof(Address),
435
                                        XIIC_STOP);
436
                if (AckByteCount != sizeof(Address)) {
437
 
438
                        /* Send is aborted so reset Tx FIFO */
439
                        XIic_WriteReg(IIC_BASE_ADDRESS,  XIIC_CR_REG_OFFSET,
440
                                        XIIC_CR_TX_FIFO_RESET_MASK);
441
                        XIic_WriteReg(IIC_BASE_ADDRESS, XIIC_CR_REG_OFFSET,
442
                                        XIIC_CR_ENABLE_DEVICE_MASK);
443
                }
444
 
445
        } while (AckByteCount != sizeof(Address));
446
 
447
 
448
        /*
449
         * Return the number of bytes written to the EEPROM
450
         */
451
        return SentByteCount - sizeof(Address);
452
}
453
 
454
/*****************************************************************************/
455
/**
456
* This function reads a number of bytes from the IIC serial EEPROM into a
457
* specified buffer.
458
*
459
* @param        Address contains the address in the EEPROM to read from.
460
* @param        BufferPtr contains the address of the data buffer to be filled.
461
* @param        ByteCount contains the number of bytes in the buffer to be read.
462
*               This value is not constrained by the page size of the device
463
*               such that up to 64K may be read in one call.
464
*
465
* @return       The number of bytes read. A value less than the specified input
466
*               value indicates an error.
467
*
468
* @note         None.
469
*
470
****************************************************************************/
471
unsigned EepromReadByte(AddressType Address, u8 *BufferPtr, u16 ByteCount)
472
{
473
        volatile unsigned ReceivedByteCount;
474
        u16 StatusReg;
475
 
476
        /*
477
         * Set the address register to the specified address by writing
478
         * the address to the device, this must be tried until it succeeds
479
         * because a previous write to the device could be pending and it
480
         * will not ack until that write is complete.
481
         */
482
        do {
483
                StatusReg = XIic_ReadReg(IIC_BASE_ADDRESS, XIIC_SR_REG_OFFSET);
484
                if(!(StatusReg & XIIC_SR_BUS_BUSY_MASK)) {
485
                        ReceivedByteCount = XIic_Send(IIC_BASE_ADDRESS,
486
                                                        EepromIicAddr,
487
                                                        (u8 *)&Address,
488
                                                        sizeof(Address),
489
                                                        XIIC_STOP);
490
 
491
                        if (ReceivedByteCount != sizeof(Address)) {
492
 
493
                                /* Send is aborted so reset Tx FIFO */
494
                                XIic_WriteReg(IIC_BASE_ADDRESS,
495
                                                XIIC_CR_REG_OFFSET,
496
                                                XIIC_CR_TX_FIFO_RESET_MASK);
497
                                XIic_WriteReg(IIC_BASE_ADDRESS,
498
                                                XIIC_CR_REG_OFFSET,
499
                                                XIIC_CR_ENABLE_DEVICE_MASK);
500
                        }
501
                }
502
 
503
        } while (ReceivedByteCount != sizeof(Address));
504
 
505
        /*
506
         * Read the number of bytes at the specified address from the EEPROM.
507
         */
508
        ReceivedByteCount = XIic_Recv(IIC_BASE_ADDRESS, EepromIicAddr,
509
                                        BufferPtr, ByteCount, XIIC_STOP);
510
 
511
        /*
512
         * Return the number of bytes read from the EEPROM.
513
         */
514
        return ReceivedByteCount;
515
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.