source: PlatformSupport/CustomPeripherals/pcores/w3_iic_eeprom_axi_v1_02_a/src/w3_iic_eeprom.c

Last change on this file was 5168, checked in by welsh, 8 years ago

Updating documentation about write-protected addresses. Updated code to protect all writes.

File size: 27.8 KB
Line 
1/*****************************************************************
2* File: w3_iic_eeprom.c
3* Copyright (c) 2012-2016 Mango Communications, all rights reserved
4* Released under the WARP License
5* See http://warp.rice.edu/license for details
6*****************************************************************/
7
8/** \file w3_iic_eeprom.c
9
10\mainpage
11This is the driver for the w3_iic_eeprom_axi core, which implements an I2C
12master for accessing the EEPROM on the WARP v3 board.
13
14This driver implements functions for reading and writing individual bytes
15in the EEPROM. Functions are also provided for accessing EEPROM entries
16written during manufacturing (serial number, etc.).
17
18The EEPROM is readable/writable from user-code.  However, addresses
19greater than 16000 are reserved and write-protected.
20
21Refer to the <a href="http://warp.rice.edu/trac/wiki/HardwareUsersGuides/WARPv3/EEPROM">WARP v3 User Guide</a>
22for details on the data written to the EEPROM during manufacturing.
23
24To allow the w3_iic_eeprom_axi core to be used as a shared peripheral in
25a multiple CPU environment, mutex functionality is implemented.  The
26mutex register, IIC_EEPROM_REG_MUTEX, has a special "lock bit" (bit 31)
27that can lock the ability to update the other bits in the register. The
28software sequence to use the mutex functionality:
29    - To lock the peripheral:
30        - Write CPU ID and Lock Bit to the mutex register
31        - Read mutex register and check if CPU ID and Lock bit matches
32            - If yes, then CPU has locked the peripheral and can update it
33            - If no, then CPU should not access peripheral
34
35    - To unlock the peripheral
36        - Write 0 to the mutex register (this will set the lock bit to zero,
37          so the register is writeable again)
38
39This approach does not have the unlock protections of the mutex peripheral
40(i.e. the mutex peripheral uses the CPU ID and potentially the bus master
41ID to enforce only the CPU who has locked the mutex is unlocking the mutex)
42but given we are not trying to protect against hacking, the sequence described
43above should be sufficient to protect the SW driver functions.
44
45In order to speed up performance in a multiple CPU environment, when the
46EEPROM is initialized, it will read all of the defined data values and then
47cache them into registers within the peripheral.  This means that future
48reads of the defined data values will be much faster, but the initialization
49of the EEPROM will take longer.  The defined data value registers are:
50    IIC_EEPROM_REG_SERIAL_NUM
51    IIC_EEPROM_REG_ETH_A_MAC_ADDR_0
52    IIC_EEPROM_REG_ETH_A_MAC_ADDR_1
53    IIC_EEPROM_REG_ETH_B_MAC_ADDR_0
54    IIC_EEPROM_REG_ETH_B_MAC_ADDR_1
55    IIC_EEPROM_REG_FPGA_DNA_0
56    IIC_EEPROM_REG_FPGA_DNA_1
57
58@version 1.02.a
59@author Patrick Murphy
60@copyright (c) 2012 Mango Communications, Inc. All rights reserved.<br>
61Released under the WARP open source license (see http://warp.rice.edu/license)
62
63\brief Main source for EEPROM controller driver
64
65*/
66
67/***************************** Include Files *********************************/
68#include "w3_iic_eeprom.h"
69#include "stdio.h"
70
71
72/*************************** Functions Prototypes ****************************/
73
74inline int    iic_eeprom_wait_for_rx_ack(u32 ba);
75u32           iic_eeprom_read_serial_num(u32 ba);
76u32           iic_eeprom_read_fpga_dna(u32 ba, int lo_hi);
77void          iic_eeprom_read_eth_addr(u32 ba, u8 addr_sel, u8* addr_buf);
78int           iic_eeprom_write_byte_internal(u32 ba, u16 addr_to_write, u8 byte_to_write);
79int           iic_eeprom_read_byte_internal(u32 ba, u16 addr_to_read);
80
81
82/******************************** Functions **********************************/
83
84
85/*****************************************************************************/
86/**
87\defgroup user_functions Functions
88\brief Functions to call from user code
89\addtogroup user_functions
90
91Example:
92\code{.c}
93// Assumes user code sets EEPROM_BASEADDR to base address of w3_iic_eeprom
94// core, as set in xparameters.h
95
96int x;
97u32 board_sn;
98u32 mutex;
99
100// Wait until you lock the EEPROM
101//     In a multiple CPU environment where the EEPROM is a shared
102//     peripheral, the EEPROM mutex must be used for the functions:
103//         - iic_eeprom_init()
104//         - iic_eeprom_write_byte()
105//         - iic_eeprom_read_byte()
106//     since these functions access the I2C bus.  All other data access
107//     functions are safe to use without the EEPROM mutex because they
108//     only access registers within the EEPROM peripheral.
109//
110do {
111    mutex = iic_eeprom_trylock(EEPROM_BASEADDR, XPAR_CPU_ID);
112   
113    //
114    // Can optionally implement a timeout that will unlock EEPROM.  For
115    // reference, the execution time of iic_eeprom_init() is roughly 15 ms on
116    // WARP v3, so any timeout should be much larger than that and greatly
117    // depends on your application.
118    //
119} while (mutex != IIC_EEPROM_READY);
120
121// Initialize the EEPROM controller
122//     - This must be run once before any other EEPROM functions are used
123iic_eeprom_init(EEPROM_BASEADDR, 0x64);
124
125// Write a value to the EEPROM (set EEPROM byte address 2345 to 182)
126x = iic_eeprom_write_byte(EEPROM_BASEADDR, 2345, 182);
127if(x != 0) xil_printf("EEPROM Write Error!\n");
128
129// Read the value back from EEPROM
130x = iic_eeprom_read_byte(EEPROM_BASEADDR, 2345);
131if(x != 182) xil_printf("EEPROM Read Error (read %d, should be 182)!\n", x);
132
133// Unlock the EEPROM
134iic_eeprom_unlock(EEPROM_BASEADDR);
135
136// Read the WARP v3 board serial number from the EEPROM
137//    - Does not need to lock the peripheral using the mutex
138board_sn = w3_eeprom_read_serial_num(EEPROM_BASEADDDR);
139xil_printf("Board s/n: W3-a-%05d\n", board_sn);
140
141\endcode
142
143@{
144*/
145
146
147
148/*****************************************************************************/
149/**
150\brief Initializes the EEPROM controller. This function must be called once at
151boot before any EEPROM read/write operations.
152
153\param ba Base memory address of w3_iic_eeprom pcore
154\param clk_div Clock divider for IIC clock (set 0x64 for 160MHz bus)
155\param id CPU ID for mutex lock
156
157\returns status:  IIC_EEPROM_SUCCESS - EEPROM Initialized
158                  IIC_EEPROM_FAILURE - EEPROM not initialized
159*/
160int iic_eeprom_init(u32 ba, u8 clk_div, u32 id) {
161    u32 status;
162    u32 tmp;
163    u8  addr_tmp[6];
164    int mutex;
165
166    // Is the peripheral initialized
167    status = Xil_In32(ba + IIC_EEPROM_REG_CONFIG_STATUS);
168   
169    if (!(status & IIC_EEPROM_REGMASK_INIT)) {
170
171        // EEPROM not initialized, try to get a mutex lock   
172        mutex = iic_eeprom_trylock(ba, id);
173       
174        if (mutex != IIC_EEPROM_READY) {
175            // Could not get a mutex lock.  Return failure. 
176            //     This condition really means that another CPU is currently
177            //     initializing the EEPROM.  It should be safe to poll on the
178            //     init until it is ready:
179            //
180            //         while (iic_eeprom_init() != IIC_EEPROM_SUCCESS) { };
181            //
182            //     since this function will return IIC_EEPROM_SUCCESS immediately
183            //     after being initialized.
184            //
185            return IIC_EEPROM_FAILURE;
186        }
187   
188        // Check status again
189        //     There is a potential race condition if two CPUs are executing this function:
190        //         1) CPU A reads status NOT_INIT  (ie enters code above to try to lock EEPROM)
191        //         2) CPU B writes status INIT (ie has EEPROM lock and has finished init)
192        //         3) CPU B unlocks EEPROM
193        //         4) CPU A executes trylock
194        //
195        //     This would cause CPU A to re-initialize the EEPROM even though CPU B
196        //     has just finished initializing the EEPROM.  Therefore, if we check
197        //     one more time here that the EEPROM is truly not initialized, then
198        //     there is no more race condition.
199        //
200        status = Xil_In32(ba + IIC_EEPROM_REG_CONFIG_STATUS);
201   
202        if (status & IIC_EEPROM_REGMASK_INIT) { return IIC_EEPROM_SUCCESS; }   
203   
204        // Configure the IIC master core
205        Xil_Out32((ba + IIC_EEPROM_REG_CMD), 0);
206        Xil_Out32((ba + IIC_EEPROM_REG_CONFIG_STATUS), (IIC_EEPROM_REGMASK_CLKDIV & clk_div));
207        Xil_Out32((ba + IIC_EEPROM_REG_CONFIG_STATUS), (Xil_In32(ba + IIC_EEPROM_REG_CONFIG_STATUS) | IIC_EEPROM_REGMASK_CORE_EN));
208
209        // Update the cached registers
210        //     The serial number should be updated before the MAC addresses because
211        //     the MAC addresses potentially use the serial number.
212        //
213       
214        // Serial Number
215        tmp = iic_eeprom_read_serial_num(ba);
216        Xil_Out32((ba + IIC_EEPROM_REG_SERIAL_NUM), tmp);
217       
218        // Ethernet A MAC Address
219        iic_eeprom_read_eth_addr(ba, 0, addr_tmp);
220       
221        tmp = ((addr_tmp[3] << 24) | (addr_tmp[2] << 16) | (addr_tmp[1] << 8) | addr_tmp[0]);
222        Xil_Out32((ba + IIC_EEPROM_REG_ETH_A_MAC_ADDR_0), tmp);
223
224        tmp = ((addr_tmp[5] << 8) | addr_tmp[4]);
225        Xil_Out32((ba + IIC_EEPROM_REG_ETH_A_MAC_ADDR_1), tmp);
226       
227        // Ethernet B MAC Address
228        iic_eeprom_read_eth_addr(ba, 1, addr_tmp);
229       
230        tmp = ((addr_tmp[3] << 24) | (addr_tmp[2] << 16) | (addr_tmp[1] << 8) | addr_tmp[0]);
231        Xil_Out32((ba + IIC_EEPROM_REG_ETH_B_MAC_ADDR_0), tmp);
232
233        tmp = ((addr_tmp[5] << 8) | addr_tmp[4]);
234        Xil_Out32((ba + IIC_EEPROM_REG_ETH_B_MAC_ADDR_1), tmp);
235       
236        // FPGA DNA       
237        tmp = iic_eeprom_read_fpga_dna(ba, 0);
238        Xil_Out32((ba + IIC_EEPROM_REG_FPGA_DNA_0), tmp);
239       
240        tmp = iic_eeprom_read_fpga_dna(ba, 1);
241        Xil_Out32((ba + IIC_EEPROM_REG_FPGA_DNA_1), tmp);
242       
243        // Set IIC_EEPROM_REGMASK_INIT bit in status register
244        Xil_Out32((ba + IIC_EEPROM_REG_CONFIG_STATUS), (Xil_In32(ba + IIC_EEPROM_REG_CONFIG_STATUS) | IIC_EEPROM_REGMASK_INIT));
245       
246        // Unlock the EEPROM
247        iic_eeprom_unlock(ba);
248    }
249
250    return IIC_EEPROM_SUCCESS;   
251}
252
253
254/*****************************************************************************/
255/**
256\brief Try to lock the EEPROM mutex
257\param ba Base memory address of w3_iic_eeprom pcore
258\param id ID value to write to the mutex
259\return Returns IIC_EEPROM_READY or IIC_EEPROM_LOCKED
260*/
261int iic_eeprom_trylock(u32 ba, u32 id) {
262    u32 mutex_wr_val;
263    u32 mutex_rd_val;
264
265    // Set value to write to mutex register
266    mutex_wr_val = (IIC_EEPROM_REGMASK_LOCK | id);
267   
268    // Write mutex register
269    Xil_Out32((ba + IIC_EEPROM_REG_MUTEX), mutex_wr_val);
270
271    // Read mutex register
272    mutex_rd_val = Xil_In32(ba + IIC_EEPROM_REG_MUTEX);
273
274    if (mutex_wr_val == mutex_rd_val) {
275        return IIC_EEPROM_READY;
276    } else {
277        return IIC_EEPROM_LOCKED;
278    }
279}
280
281
282
283/*****************************************************************************/
284/**
285\brief Unlock the EEPROM mutex
286\param ba Base memory address of w3_iic_eeprom pcore
287*/
288void iic_eeprom_unlock(u32 ba) {
289    // Set mutex register to zero
290    Xil_Out32((ba + IIC_EEPROM_REG_MUTEX), 0);
291   
292    //
293    // By only writing 0 to the mutex register once, this allows the mutex
294    // register to retain the last ID that was used to lock the mutex (ie the
295    // only lock bit is set to zero).  This might be useful for debug in the
296    // future and will not affect subsequent writes to the mutex register.
297    //
298}
299
300
301
302/*****************************************************************************/
303/**
304\brief Writes one bytes to the EEPROM
305
306This method will return IIC_EEPROM_FAILURE if it fails to obtain a mutex lock. 
307It will unlock the mutex after writing the byte.  The calling function must
308check the output value is not IIC_EEPROM_FAILURE before proceeding to write the
309next byte.
310
311NOTE:  Addresses greater than 16000 are reserved for manufacturing information.
312    These addresses are not write protected but modifying them can cause issues
313    with the behaviour of the node.
314
315\param ba Base memory address of w3_iic_eeprom peripheral
316\param addr_to_write Byte address to write, in [0,16000] (addresses > 16000 are reserved)
317\param byte_to_write Byte value to write
318\return Returns IIC_EEPROM_SUCCESS if EEPROM write succeeds. Returns
319    IIC_EEPROM_FAILURE if an error occurs.
320*/
321int iic_eeprom_write_byte(u32 ba, u16 addr_to_write, u8 byte_to_write, u32 id)
322{
323    int status;
324    int mutex;
325   
326    // Try to get a mutex lock
327    mutex = iic_eeprom_trylock(ba, id);
328       
329    if (mutex != IIC_EEPROM_READY) {
330        // Could not get a mutex lock.  Return failure. 
331        return IIC_EEPROM_FAILURE;
332    }
333
334    // Write the byte using the internal method
335    status = iic_eeprom_write_byte_internal(ba, addr_to_write, byte_to_write);
336   
337    // Unlock the EEPROM
338    iic_eeprom_unlock(ba);
339   
340    return status;
341}
342
343
344
345/*****************************************************************************/
346/**
347\brief Reads one bytes to the EEPROM
348
349This method will return IIC_EEPROM_FAILURE if it fails to obtain a mutex lock. 
350It will unlock the mutex after reading the byte.  The calling function must
351check the output value is not IIC_EEPROM_FAILURE before proceeding to read the
352next byte.
353
354\param ba Base memory address of w3_iic_eeprom peripheral
355\param addr_to_read Byte address to read (in [0, 16383])
356\return If EEPROM read succeeds, the read byte is returned in the LSB. If an
357    error occurs, returns IIC_EEPROM_FAILURE.
358*/
359int iic_eeprom_read_byte(u32 ba, u16 addr_to_read, u32 id)
360{
361    int value;
362    int mutex;
363   
364    // Try to get a mutex lock
365    mutex = iic_eeprom_trylock(ba, id);
366       
367    if (mutex != IIC_EEPROM_READY) {
368        // Could not get a mutex lock.  Return failure. 
369        return IIC_EEPROM_FAILURE;
370    }
371
372    // Read the byte using the internal method
373    value = iic_eeprom_read_byte_internal(ba, addr_to_read);
374   
375    // Unlock the EEPROM
376    iic_eeprom_unlock(ba);
377   
378    return value;
379}
380
381
382
383/*****************************************************************************/
384/**
385\brief Reads the WARP v3 board serial number (programmed during manufacturing)
386\param ba Base memory address of w3_iic_eeprom pcore
387\return Numeric part of board serial number (prefix "W3-a-" not stored in EEPROM)
388*/
389u32 w3_eeprom_read_serial_num(u32 ba)
390{
391    u32 status;
392
393    status = Xil_In32(ba + IIC_EEPROM_REG_CONFIG_STATUS);
394   
395    if (!(status & IIC_EEPROM_REGMASK_INIT)) {
396        xil_printf("WARNING: EEPROM not initialized\n");
397        return 0;
398    }
399
400    return (Xil_In32(ba + IIC_EEPROM_REG_SERIAL_NUM));
401}
402
403
404
405/*****************************************************************************/
406/**
407\brief Reads one of the WARP v3 board Ethernet MAC addresses (programmed during manufacturing)
408\param ba Base memory address of w3_iic_eeprom pcore
409\param addr_sel Selection of Ethernet address to retrieve (0=ETH_A address, 1=ETH_B address)
410\param addr_buf Pointer to array of 6 bytes to store retrieved address. This function will overwrite 6 bytes starting at addr_buf.
411*/
412void w3_eeprom_read_eth_addr(u32 ba, u8 addr_sel, u8* addr_buf)
413{
414    u32 status;
415    u32 tmp_0;
416    u32 tmp_1;
417
418    // Check that the cached copy has been initialized
419    status = Xil_In32(ba + IIC_EEPROM_REG_CONFIG_STATUS);
420   
421    if (!(status & IIC_EEPROM_REGMASK_INIT)) {
422        xil_printf("WARNING: EEPROM not initialized\n");
423       
424        // Update the address buffer
425        addr_buf[0] = 0;
426        addr_buf[1] = 0;
427        addr_buf[2] = 0;
428        addr_buf[3] = 0;
429        addr_buf[4] = 0;
430        addr_buf[5] = 0;
431       
432    } else {
433        // Get cached copy of MAC Address
434        if (addr_sel == 0) {
435            // Ethernet A MAC Address
436            tmp_0 = Xil_In32(ba + IIC_EEPROM_REG_ETH_A_MAC_ADDR_0);
437            tmp_1 = Xil_In32(ba + IIC_EEPROM_REG_ETH_A_MAC_ADDR_1);
438        } else {
439            // Ethernet B MAC Address
440            tmp_0 = Xil_In32(ba + IIC_EEPROM_REG_ETH_B_MAC_ADDR_0);
441            tmp_1 = Xil_In32(ba + IIC_EEPROM_REG_ETH_B_MAC_ADDR_1);
442        }   
443
444        // Update the address buffer
445        addr_buf[0] = (tmp_0 & 0x000000FF);
446        addr_buf[1] = (tmp_0 & 0x0000FF00) >>  8;
447        addr_buf[2] = (tmp_0 & 0x00FF0000) >> 16;
448        addr_buf[3] = (tmp_0 & 0xFF000000) >> 24;
449        addr_buf[4] = (tmp_1 & 0x000000FF);
450        addr_buf[5] = (tmp_1 & 0x0000FF00) >>  8;
451    }   
452}
453
454
455
456/*****************************************************************************/
457/**
458\brief Reads part of the 56-bit Virtex-6 FPGA DNA value (copied to EEPROM during manufacturing)
459\param ba Base memory address of w3_iic_eeprom pcore
460\param lo_hi Selects between 32 LSB or 24 MSB of DNA value (0=LSB, 1=MSB)
461\return Returns selected portion of FPGA DNA value
462*/
463u32 w3_eeprom_read_fpga_dna(u32 ba, int lo_hi)
464{
465    u32 status;
466   
467    // Check that the cached copy has been initialized
468    status = Xil_In32(ba + IIC_EEPROM_REG_CONFIG_STATUS);
469   
470    if (!(status & IIC_EEPROM_REGMASK_INIT)) {
471        xil_printf("WARNING: EEPROM not initialized\n");
472        return 0;
473    }
474   
475    // Return cached copy of FPGA DNA
476    if (lo_hi == 0) {
477        return (Xil_In32(ba + IIC_EEPROM_REG_FPGA_DNA_0));
478    } else {
479        return (Xil_In32(ba + IIC_EEPROM_REG_FPGA_DNA_1));
480    }
481}
482
483/** @}*/ //END group user_functions
484
485/// @cond EXCLUDE_FROM_DOCS
486
487/***************************** Local Functions *******************************/
488
489/*****************************************************************************/
490/**
491\brief Reads the WARP v3 board serial number (programmed during manufacturing)
492\param ba Base memory address of w3_iic_eeprom pcore
493\return Numeric part of board serial number (prefix "W3-a-" not stored in EEPROM)
494*/
495u32 iic_eeprom_read_serial_num(u32 ba)
496{
497    int x0, x1, x2;
498
499    x0 = (int) iic_eeprom_read_byte_internal(ba, 16372);
500    x1 = (int) iic_eeprom_read_byte_internal(ba, 16373);
501    x2 = (int) iic_eeprom_read_byte_internal(ba, 16374);
502
503    return ((x2 << 16) | (x1 << 8) | x0);
504}
505
506
507
508/*****************************************************************************/
509/**
510\brief Reads one of the WARP v3 board Ethernet MAC addresses (programmed during manufacturing)
511\param ba Base memory address of w3_iic_eeprom pcore
512\param addr_sel Selection of Ethernet address to retrieve (0=ETH_A address, 1=ETH_B address)
513\param addr_buf Pointer to array of 6 bytes to store retrieved address. This function will overwrite 6 bytes starting at addr_buf.
514*/
515void iic_eeprom_read_eth_addr(u32 ba, u8 addr_sel, u8* addr_buf)
516{
517    u8 addr_offset;
518    u32 sn;
519
520    addr_offset = addr_sel ? 6 : 0;
521
522    addr_buf[5] = iic_eeprom_read_byte_internal(ba, (16352 + addr_offset));
523    addr_buf[4] = iic_eeprom_read_byte_internal(ba, (16353 + addr_offset));
524    addr_buf[3] = iic_eeprom_read_byte_internal(ba, (16354 + addr_offset));
525    addr_buf[2] = iic_eeprom_read_byte_internal(ba, (16355 + addr_offset));
526    addr_buf[1] = iic_eeprom_read_byte_internal(ba, (16356 + addr_offset));
527    addr_buf[0] = iic_eeprom_read_byte_internal(ba, (16357 + addr_offset));
528
529    if (((addr_buf[0] == 0x40) && (addr_buf[1] == 0xD8) && (addr_buf[2] == 0x55)) == 0) {
530        // EEPROM contains invalid (or no) MAC address
531        //     - Use the node serial number to compute a valid address instead
532        //     - See http://warpproject.org/trac/wiki/HardwareUsersGuides/WARPv3/Ethernet#MACAddresses
533        //
534        sn          = 2 * Xil_In32(ba + IIC_EEPROM_REG_SERIAL_NUM);
535       
536        addr_buf[0] = 0x40;
537        addr_buf[1] = 0xD8;
538        addr_buf[2] = 0x55;
539        addr_buf[3] = 0x04;
540        addr_buf[4] = 0x20 + ((sn >> 8) & 0xF);
541        addr_buf[5] = 0x00 + (sn & 0xFF) + (addr_sel & 0x1);
542    }
543   
544    // If the first three octets match, then the node has a serial number that does not follow the
545    // serial_number * 2 scheme.  However, we still need to check to make sure that octet [3] and [4]
546    // are correct.
547    if (addr_buf[3] != 0x04) {                         // addr_buf[3] must be 0x04
548        addr_buf[3] = 0x04; 
549    }   
550
551    if ((addr_buf[4] & 0xF0) != 0x20) {                // addr_buf[4] must be 0x2X, where X is in [0..F]
552        addr_buf[4] = 0x20 | (addr_buf[4] & 0x0F); 
553    }
554}
555
556
557
558/*****************************************************************************/
559/**
560\brief Reads part of the 56-bit Virtex-6 FPGA DNA value (copied to EEPROM during manufacturing)
561\param ba Base memory address of w3_iic_eeprom pcore
562\param lo_hi Selects between 32 LSB or 24 MSB of DNA value (0=LSB, 1=MSB)
563\return Returns selected portion of FPGA DNA value
564*/
565u32 iic_eeprom_read_fpga_dna(u32 ba, int lo_hi)
566{
567    int x0, x1, x2, x3;
568   
569    if (lo_hi == 0) {
570        x0 = (int) iic_eeprom_read_byte_internal(ba, 16376);
571        x1 = (int) iic_eeprom_read_byte_internal(ba, 16377);
572        x2 = (int) iic_eeprom_read_byte_internal(ba, 16378);
573        x3 = (int) iic_eeprom_read_byte_internal(ba, 16379);
574       
575    } else if (lo_hi == 1) {
576        x0 = (int) iic_eeprom_read_byte_internal(ba, 16380);
577        x1 = (int) iic_eeprom_read_byte_internal(ba, 16381);
578        x2 = (int) iic_eeprom_read_byte_internal(ba, 16382);
579        x3 = (int) iic_eeprom_read_byte_internal(ba, 16383);
580
581    } else {
582        return 0;
583    }
584
585    return ((x3 << 24) | (x2 << 16) | (x1 << 8) | x0);
586}
587
588
589
590/*****************************************************************************/
591/**
592\brief Writes one bytes to the EEPROM
593
594\param ba Base memory address of w3_iic_eeprom pcore
595\param addr_to_write Byte address to write, in [0,16000] (addresses >16000 are reserved)
596\param byte_to_write Byte value to write
597\return Returns 0 if EEPROM write succeeds. Returns -1 if an error occurs.
598*/
599int iic_eeprom_write_byte_internal(u32 ba, u16 addr_to_write, u8 byte_to_write)
600{
601    int write_done;
602   
603    /* Process to write 1 byte to random address in IIC EEPROM
604        - Write EEPROM control word to Tx register {1 0 1 0 0 0 0 RNW}, RNW=0
605            - Assert START and WRITE command bits
606            - Poll TIP bit, wait for TIP=0
607            - Read RXACK status bit, should be 0
608        - Write top 8 bits of target address to Tx register
609            - Assert WRITE command bit
610            - Poll TIP bit, wait for TIP=0
611            - Read RXACK status bit, should be 0
612        - Write bottom 8 bits of target address to Tx register
613            - Assert WRITE command bit
614            - Poll TIP bit, wait for TIP=0
615            - Read RXACK status bit, should be 0
616        - Write data byte to Tx register
617            - Assert STOP and WRITE command bits
618            - Poll TIP bit, wait for TIP=0
619            - Read RXACK status bit, should be 0
620    */
621
622// Protect upper EEPROM bytes   
623#if 1
624    if(addr_to_write > 16000) {
625        xil_printf("ERROR! High bytes read-only by default. Edit %s to override!\n", __FILE__);
626        return IIC_EEPROM_FAILURE;
627    }
628#endif
629
630    Xil_Out32((ba + IIC_EEPROM_REG_TX), (IIC_EEPROM_CONTROL_WORD_WR));
631    Xil_Out32((ba + IIC_EEPROM_REG_CMD), (IIC_EEPROM_REGMASK_START | IIC_EEPROM_REGMASK_WRITE));
632    if (iic_eeprom_wait_for_rx_ack(ba)) { print("EEPROM: WR Error (1)!\r"); return IIC_EEPROM_FAILURE; }
633
634    Xil_Out32((ba + IIC_EEPROM_REG_TX), ((addr_to_write >> 8) & 0xFF));
635    Xil_Out32((ba + IIC_EEPROM_REG_CMD), (IIC_EEPROM_REGMASK_WRITE));
636    if (iic_eeprom_wait_for_rx_ack(ba)) { print("EEPROM: WR Error (2)!\r"); return IIC_EEPROM_FAILURE; }
637
638    Xil_Out32((ba + IIC_EEPROM_REG_TX), (addr_to_write & 0xFF));
639    Xil_Out32((ba + IIC_EEPROM_REG_CMD), (IIC_EEPROM_REGMASK_WRITE));
640    if (iic_eeprom_wait_for_rx_ack(ba)) { print("EEPROM: WR Error (3)!\r"); return IIC_EEPROM_FAILURE; }
641
642    Xil_Out32((ba + IIC_EEPROM_REG_TX), (byte_to_write & 0xFF));
643    Xil_Out32((ba + IIC_EEPROM_REG_CMD), (IIC_EEPROM_REGMASK_STOP | IIC_EEPROM_REGMASK_WRITE));
644    if (iic_eeprom_wait_for_rx_ack(ba)) { print("EEPROM: WR Error (4)!\r"); return IIC_EEPROM_FAILURE; }
645
646    /* Poll the EEPROM until its internal write cycle is complete
647       This is done by:
648          - Send START
649          - Write control word for write command
650         - Check for ACK; no ACK means internal write is still ongoing
651    */
652    write_done = 0;
653   
654    while (write_done == 0)
655    {
656        Xil_Out32((ba + IIC_EEPROM_REG_TX), (IIC_EEPROM_CONTROL_WORD_WR));
657        Xil_Out32((ba + IIC_EEPROM_REG_CMD), (IIC_EEPROM_REGMASK_START | IIC_EEPROM_REGMASK_WRITE));
658        if (iic_eeprom_wait_for_rx_ack(ba) == 0) { write_done = 1; }
659    }
660
661    return IIC_EEPROM_SUCCESS;
662}
663
664
665
666/*****************************************************************************/
667/**
668\brief Reads one bytes to the EEPROM
669
670\param ba Base memory address of w3_iic_eeprom pcore
671\param addr_to_read Byte address to read (in [0,16383])
672\return If EEPROM read succeeds, the read byte is returned in the LSB. If an error occurs, returns -1.
673*/
674int iic_eeprom_read_byte_internal(u32 ba, u16 addr_to_read)
675{
676    /* Process to read 1 byte from random address in IIC EEPROM
677        - Write EEPROM control word to Tx register {1 0 1 0 0 0 0 RNW}, RNW=0
678            - Assert START and WRITE command bits
679            - Poll TIP bit, wait for TIP=0
680            - Read RXACK status bit, should be 0
681        - Write top 8 bits of target address to Tx register
682            - Assert WRITE command bit
683            - Poll TIP bit, wait for TIP=0
684            - Read RXACK status bit, should be 0
685        - Write bottom 8 bits of target address to Tx register
686            - Assert WRITE command bit
687            - Poll TIP bit, wait for TIP=0
688            - Read RXACK status bit, should be 0
689        - Write EEPROM control word to Tx register {1 0 1 0 0 0 0 RNW}, RNW=1
690            - Assert START and WRITE command bits (causes repeat START event)
691            - Poll TIP bit, wait for TIP=0
692            - Read RXACK status bit, should be 0
693        - Assert STOP, READ and ACK command bits
694        - Read received byte from rx register
695    */
696
697    Xil_Out32((ba + IIC_EEPROM_REG_TX), (IIC_EEPROM_CONTROL_WORD_WR));
698    Xil_Out32((ba + IIC_EEPROM_REG_CMD), (IIC_EEPROM_REGMASK_START | IIC_EEPROM_REGMASK_WRITE));
699    if (iic_eeprom_wait_for_rx_ack(ba)) { print("EEPROM: RD Error (1)!\r"); return IIC_EEPROM_FAILURE; }
700
701    Xil_Out32((ba + IIC_EEPROM_REG_TX), ((addr_to_read >> 8) & 0xFF));
702    Xil_Out32((ba + IIC_EEPROM_REG_CMD), (IIC_EEPROM_REGMASK_WRITE));
703    if (iic_eeprom_wait_for_rx_ack(ba)) { print("EEPROM: RD Error (2)!\r"); return IIC_EEPROM_FAILURE; }
704
705    Xil_Out32((ba + IIC_EEPROM_REG_TX), (addr_to_read & 0xFF));
706    Xil_Out32((ba + IIC_EEPROM_REG_CMD), (IIC_EEPROM_REGMASK_WRITE));
707    if (iic_eeprom_wait_for_rx_ack(ba)) { print("EEPROM: RD Error (3)!\r"); return IIC_EEPROM_FAILURE; }
708
709    Xil_Out32((ba + IIC_EEPROM_REG_TX), (IIC_EEPROM_CONTROL_WORD_RD));
710    Xil_Out32((ba + IIC_EEPROM_REG_CMD), (IIC_EEPROM_REGMASK_START | IIC_EEPROM_REGMASK_WRITE));
711    if (iic_eeprom_wait_for_rx_ack(ba)) { print("EEPROM: RD Error (4)!\r"); return IIC_EEPROM_FAILURE; }
712
713    Xil_Out32((ba + IIC_EEPROM_REG_CMD), (IIC_EEPROM_REGMASK_STOP | IIC_EEPROM_REGMASK_READ | IIC_EEPROM_REGMASK_ACK));
714    while(Xil_In32(ba+IIC_EEPROM_REG_CONFIG_STATUS) & IIC_EEPROM_REGMASK_TIP) {}
715
716    return (Xil_In32(ba + IIC_EEPROM_REG_RX) & 0xFF);
717}
718
719
720
721/*****************************************************************************/
722/**
723\brief Wait for receive acknowledgement
724\param ba Base memory address of w3_iic_eeprom pcore
725\return Returns 0 if IIC bus ACK is detected
726*/
727inline int iic_eeprom_wait_for_rx_ack(u32 ba)
728{
729//     xil_printf("Status: 0x%08x CMD: 0x%08x\r", Xil_In32(ba+IIC_EEPROM_REG_CONFIG_STATUS), Xil_In32(ba+IIC_EEPROM_REG_CMD));
730
731    while(Xil_In32(ba+IIC_EEPROM_REG_CONFIG_STATUS) & IIC_EEPROM_REGMASK_TIP) {}
732
733    return (0 != (Xil_In32(ba+IIC_EEPROM_REG_CONFIG_STATUS) & IIC_EEPROM_REGMASK_RXACK));
734}
735
736
737/// @endcond
Note: See TracBrowser for help on using the repository browser.