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

Last change on this file was 1863, checked in by murphpo, 11 years ago

Adding/updating cores for FMC radio module

File size: 10.1 KB
Line 
1/*****************************************************************
2* File: w3_iic_eeprom.c
3* Copyright (c) 2012 Mango Communications, all rights reseved
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 core, which implements an IIC master for accessing
12the EEPROM on the WARP v3 board.
13
14This driver implements functions for reading and writing individual bytes in the EEPROM. Functions
15are also provided for accessing EEPROM entries written during manufacturing (serial number, etc.).
16
17The full EEPROM is readable/writable from user-code. No addresses are write-protected.
18
19Refer to the <a href="http://warp.rice.edu/trac/wiki/HardwareUsersGuides/WARPv3/EEPROM">WARP v3 User Guide</a> for details
20on the data written to the EEPROM during manufacturing.
21
22@version 1.00.b
23@author Patrick Murphy
24@copyright (c) 2012 Mango Communications, Inc. All rights reserved.<br>
25Released under the WARP open source license (see http://warp.rice.edu/license)
26
27\brief Main source for EEPROM controller driver
28
29*/
30
31#include "w3_iic_eeprom.h"
32#include "stdio.h"
33
34/**
35\defgroup user_functions Functions
36\brief Functions to call from user code
37\addtogroup user_functions
38
39Example:
40\code{.c}
41//Assumes user code sets EEPROM_BASEADDR to base address of w3_iic_eeprom core, as set in xparameters.h
42
43int x;
44u32 board_sn;
45
46//Initialize the EEPROM controller at boot
47iic_eeprom_init(EEPROM_BASEADDR, 0x64);
48
49//Write a value to the EEPROM (set EEPROM byte address 2345 to 182)
50x = iic_eeprom_writeByte(EEPROM_BASEADDR, 2345, 182);
51if(x != 0) xil_printf("EEPROM Write Error!\n");
52
53//Read the value back from EEPROM
54x = iic_eeprom_readByte(EEPROM_BASEADDR, 2345);
55if(x != 182) xil_printf("EEPROM Read Error (read %d, should be 182)!\n", x);
56
57//Read the WARP v3 board serial number from the EEPROM
58board_sn = w3_eeprom_readSerialNum(EEPROM_BASEADDDR);
59xil_printf("Board s/n: W3-a-%05d\n", board_sn);
60
61\endcode
62
63@{
64*/
65
66/**
67\brief Initializes the EEPROM controller. This function must be called once at boot before any EEPROM read/write operations.
68\param ba Base memory address of w3_iic_eeprom pcore
69\param clkDiv Clock divider for IIC clock (set 0x64 for 160MHz bus)
70*/
71void iic_eeprom_init(u32 ba, u8 clkDiv)
72{
73    //Configure the IIC master core
74    Xil_Out32(ba+IIC_EEPROM_REG_CMD, 0);
75    Xil_Out32(ba+IIC_EEPROM_REG_CONFIG_STATUS, (IIC_EEPROM_REGMASK_CLKDIV & clkDiv));
76    Xil_Out32(ba+IIC_EEPROM_REG_CONFIG_STATUS, Xil_In32(ba+IIC_EEPROM_REG_CONFIG_STATUS) | IIC_EEPROM_REGMASK_COREEN);
77
78    return;
79}
80
81/**
82\brief Writes one bytes to the EEPROM
83\param ba Base memory address of w3_iic_eeprom pcore
84\param addrToWrite Byte address to write, in [0,16000] (addresses >16000 are reserved)
85\param byteToWrite Byte value to write
86\return Returns 0 if EEPROM write succeeds. Returns -1 if an error occurs.
87*/
88int iic_eeprom_writeByte(u32 ba, u16 addrToWrite, u8 byteToWrite)
89{
90    int writeDone;
91    /* Process to write 1 byte to random address in IIC EEPROM
92        - Write EEPROM control word to Tx register {1 0 1 0 0 0 0 RNW}, RNW=0
93            - Assert START and WRITE command bits
94            - Poll TIP bit, wait for TIP=0
95            - Read RXACK status bit, should be 0
96        - Write top 8 bits of target address to Tx register
97            - Assert WRITE command bit
98            - Poll TIP bit, wait for TIP=0
99            - Read RXACK status bit, should be 0
100        - Write bottom 8 bits of target address to Tx register
101            - Assert WRITE command bit
102            - Poll TIP bit, wait for TIP=0
103            - Read RXACK status bit, should be 0
104        - Write data byte to Tx register
105            - Assert STOP and WRITE command bits
106            - Poll TIP bit, wait for TIP=0
107            - Read RXACK status bit, should be 0
108    */
109    #if 1 //protect upper EEPROM bytes
110    if(addrToWrite > 16000) {
111        xil_printf("ERROR! High bytes read-only by default. Edit %s to override!\n", __FILE__);
112        return -1;
113    }
114    #endif
115
116    Xil_Out32(ba+IIC_EEPROM_REG_TX, IIC_EEPROM_CONTROL_WORD_WR);
117    Xil_Out32(ba+IIC_EEPROM_REG_CMD, (IIC_EEPROM_REGMASK_START | IIC_EEPROM_REGMASK_WRITE));
118    if(iic_eeprom_waitForRxACK(ba)) {print("EEPROM: Error (1)!\r"); return -1;}
119
120    Xil_Out32(ba+IIC_EEPROM_REG_TX, (addrToWrite>>8 & 0xFF));
121    Xil_Out32(ba+IIC_EEPROM_REG_CMD, (IIC_EEPROM_REGMASK_WRITE));
122    if(iic_eeprom_waitForRxACK(ba)) {print("EEPROM: Error (2)!\r"); return -1;}
123
124    Xil_Out32(ba+IIC_EEPROM_REG_TX, (addrToWrite & 0xFF));
125    Xil_Out32(ba+IIC_EEPROM_REG_CMD, (IIC_EEPROM_REGMASK_WRITE));
126    if(iic_eeprom_waitForRxACK(ba)) {print("EEPROM: Error (3)!\r"); return -1;}
127
128    Xil_Out32(ba+IIC_EEPROM_REG_TX, (byteToWrite & 0xFF));
129    Xil_Out32(ba+IIC_EEPROM_REG_CMD, (IIC_EEPROM_REGMASK_STOP | IIC_EEPROM_REGMASK_WRITE));
130    if(iic_eeprom_waitForRxACK(ba)) {print("EEPROM: Error (4)!\r"); return -1;}
131
132    /* Poll the EEPROM until its internal write cycle is complete
133       This is done by:
134        -Send START
135        -Write control word for write command
136        -Check for ACK; no ACK means internal write is still ongoing
137    */
138    writeDone = 0;
139    while(writeDone == 0)
140    {
141        Xil_Out32(ba+IIC_EEPROM_REG_TX, IIC_EEPROM_CONTROL_WORD_WR);
142        Xil_Out32(ba+IIC_EEPROM_REG_CMD, (IIC_EEPROM_REGMASK_START | IIC_EEPROM_REGMASK_WRITE));
143        if(iic_eeprom_waitForRxACK(ba) == 0) {writeDone = 1;}
144    }
145
146    return 0;
147}
148
149/**
150\brief Reads one bytes to the EEPROM
151\param ba Base memory address of w3_iic_eeprom pcore
152\param addrToRead Byte address to read (in [0,16383])
153\return If EEPROM read succeeds, the read byte is returned in the LSB. If an error occurs, returns -1.
154*/
155int iic_eeprom_readByte(u32 ba, u16 addrToRead)
156{
157    /* Process to read 1 byte from random address in IIC EEPROM
158        - Write EEPROM control word to Tx register {1 0 1 0 0 0 0 RNW}, RNW=0
159            - Assert START and WRITE command bits
160            - Poll TIP bit, wait for TIP=0
161            - Read RXACK status bit, should be 0
162        - Write top 8 bits of target address to Tx register
163            - Assert WRITE command bit
164            - Poll TIP bit, wait for TIP=0
165            - Read RXACK status bit, should be 0
166        - Write bottom 8 bits of target address to Tx register
167            - Assert WRITE command bit
168            - Poll TIP bit, wait for TIP=0
169            - Read RXACK status bit, should be 0
170        - Write EEPROM control word to Tx register {1 0 1 0 0 0 0 RNW}, RNW=1
171            - Assert START and WRITE command bits (causes repeat START event)
172            - Poll TIP bit, wait for TIP=0
173            - Read RXACK status bit, should be 0
174        - Assert STOP, READ and ACK command bits
175        - Read received byte from rx register
176    */
177
178
179    Xil_Out32(ba+IIC_EEPROM_REG_TX, IIC_EEPROM_CONTROL_WORD_WR);
180    Xil_Out32(ba+IIC_EEPROM_REG_CMD, (IIC_EEPROM_REGMASK_START | IIC_EEPROM_REGMASK_WRITE));
181    if(iic_eeprom_waitForRxACK(ba)) {print("EEPROM: Error (1)!\r"); return -1;}
182
183    Xil_Out32(ba+IIC_EEPROM_REG_TX, (addrToRead>>8 & 0xFF));
184    Xil_Out32(ba+IIC_EEPROM_REG_CMD, (IIC_EEPROM_REGMASK_WRITE));
185    if(iic_eeprom_waitForRxACK(ba)) {print("EEPROM: Error (2)!\r"); return -1;}
186
187    Xil_Out32(ba+IIC_EEPROM_REG_TX, (addrToRead & 0xFF));
188    Xil_Out32(ba+IIC_EEPROM_REG_CMD, (IIC_EEPROM_REGMASK_WRITE));
189    if(iic_eeprom_waitForRxACK(ba)) {print("EEPROM: Error (3)!\r"); return -1;}
190
191    Xil_Out32(ba+IIC_EEPROM_REG_TX, IIC_EEPROM_CONTROL_WORD_RD);
192    Xil_Out32(ba+IIC_EEPROM_REG_CMD, (IIC_EEPROM_REGMASK_START | IIC_EEPROM_REGMASK_WRITE));
193    if(iic_eeprom_waitForRxACK(ba)) {print("EEPROM: Error (4)!\r"); return -1;}
194
195    Xil_Out32(ba+IIC_EEPROM_REG_CMD, (IIC_EEPROM_REGMASK_STOP | IIC_EEPROM_REGMASK_READ | IIC_EEPROM_REGMASK_ACK));
196    while(Xil_In32(ba+IIC_EEPROM_REG_CONFIG_STATUS) & IIC_EEPROM_REGMASK_TIP) {}
197
198    return (Xil_In32(ba+IIC_EEPROM_REG_RX) & 0xFF);
199
200}
201
202/**
203\brief Reads the WARP v3 board serial number (programmed during manufacturing)
204\param ba Base memory address of w3_iic_eeprom pcore
205\return Numeric part of board serial number (prefix "W3-a-" not stored in EEPROM)
206*/
207u32 w3_eeprom_readSerialNum(u32 ba)
208{
209    int x0,x1,x2;
210
211    x0 = (int)iic_eeprom_readByte(ba, 16372);
212    x1 = (int)iic_eeprom_readByte(ba, 16373);
213    x2 = (int)iic_eeprom_readByte(ba, 16374);
214
215    return (x2<<16 | x1<<8 | x0);
216}
217
218/**
219\brief Reads one of the WARP v3 board Ethernet MAC addresses (programmed during manufacturing)
220\param ba Base memory address of w3_iic_eeprom pcore
221\param addrSel Selection of Ethernet address to retrieve (0=ETH_A address, 1=ETH_B address)
222\param addrBuf Pointer to array of 6 bytes to store retrieved address. This function will overwrite 6 bytes starting at addrBuf.
223*/
224void w3_eeprom_readEthAddr(u32 ba, u8 addrSel, u8* addrBuf)
225{
226    u8 addrOffset;
227
228    addrOffset = addrSel ? 6 : 0;
229   
230    addrBuf[5] = iic_eeprom_readByte(ba, 16352+addrOffset);
231    addrBuf[4] = iic_eeprom_readByte(ba, 16353+addrOffset);
232    addrBuf[3] = iic_eeprom_readByte(ba, 16354+addrOffset);
233    addrBuf[2] = iic_eeprom_readByte(ba, 16355+addrOffset);
234    addrBuf[1] = iic_eeprom_readByte(ba, 16356+addrOffset);
235    addrBuf[0] = iic_eeprom_readByte(ba, 16357+addrOffset);
236
237    return;
238}
239
240/**
241\brief Reads part of the 56-bit Virtex-6 FPGA DNA value (copied to EEPROM during manufacturing)
242\param ba Base memory address of w3_iic_eeprom pcore
243\param lo_hi Selects between 32 LSB or 24 MSB of DNA value (0=LSB, 1=MSB)
244\return Returns selected portion of FPGA DNA value
245*/
246u32 w3_eeprom_read_fpga_dna(u32 ba, int lo_hi)
247{
248    int x0,x1,x2,x3;
249    if(lo_hi==0)
250    {
251        x0 = (int)iic_eeprom_readByte(ba, 16376);
252        x1 = (int)iic_eeprom_readByte(ba, 16377);
253        x2 = (int)iic_eeprom_readByte(ba, 16378);
254        x3 = (int)iic_eeprom_readByte(ba, 16379);
255    }
256    else if(lo_hi==1)
257    {
258        x0 = (int)iic_eeprom_readByte(ba, 16380);
259        x1 = (int)iic_eeprom_readByte(ba, 16381);
260        x2 = (int)iic_eeprom_readByte(ba, 16382);
261        x3 = (int)iic_eeprom_readByte(ba, 16383);
262    }
263
264    return (x3<<24 | x2<<16 | x1<<8 | x0);
265}
266/** @}*/ //END group user_functions
267
268/// @cond EXCLUDE_FROM_DOCS
269// User code never calls this, so exclude it from the API docs
270//Returns 0 if IIC bus ACK is detected
271inline int iic_eeprom_waitForRxACK(u32 ba)
272{
273//  xil_printf("Status: 0x%08x CMD: 0x%08x\r", Xil_In32(ba+IIC_EEPROM_REG_CONFIG_STATUS), Xil_In32(ba+IIC_EEPROM_REG_CMD));
274    while(Xil_In32(ba+IIC_EEPROM_REG_CONFIG_STATUS) & IIC_EEPROM_REGMASK_TIP) {}
275
276    return (0 != (Xil_In32(ba+IIC_EEPROM_REG_CONFIG_STATUS) & IIC_EEPROM_REGMASK_RXACK));
277}
278/// @endcond
Note: See TracBrowser for help on using the repository browser.