1 | /* Copyright (c) 2006 Rice University */ |
---|
2 | /* All Rights Reserved */ |
---|
3 | /* This code is covered by the Rice-WARP license */ |
---|
4 | /* See http://warp.rice.edu/license/ for details */ |
---|
5 | |
---|
6 | |
---|
7 | ////////////////////////////////////////////////////////////////////////////// |
---|
8 | // Filename: C:\EDK_User_Repository\WARP\drivers\EEPROM_v1_00_a\src\EEPROM.c |
---|
9 | // Version: 1.00.a |
---|
10 | // Description: EEPROM Driver Source File |
---|
11 | // Date: July 28, 2006 |
---|
12 | ////////////////////////////////////////////////////////////////////////////// |
---|
13 | |
---|
14 | |
---|
15 | /***************************** Include Files *******************************/ |
---|
16 | |
---|
17 | #include "EEPROM.h" |
---|
18 | #include "xparameters.h" |
---|
19 | #include <stdlib.h> |
---|
20 | |
---|
21 | /****************************WARP LIBRARIES**************************/ |
---|
22 | |
---|
23 | // Choose the EEPROM to be affected by subsequent reads/writes |
---|
24 | // EEPROM_select selects the appropriate EEPROM to drive |
---|
25 | // Defaults to FPGA Board |
---|
26 | // 0: FPGA Board 1: Radio1 2: Radio2 3: Radio3 4: Radio4 |
---|
27 | // Returns SUCCESS if clock set correctly |
---|
28 | // Returns FAILURE otherwise |
---|
29 | char WarpEEPROM_EEPROMSelect(unsigned int* baseaddr, char EEPROM_select) |
---|
30 | { |
---|
31 | if(EEPROM_select > 4) |
---|
32 | return FAILURE; |
---|
33 | |
---|
34 | Xuint8 CMD_REG; |
---|
35 | |
---|
36 | CMD_REG = EEPROM_mReadReg((volatile)baseaddr, 0x0); |
---|
37 | |
---|
38 | EEPROM_mWriteReg((volatile)baseaddr, 0x0, (CMD_REG & 0x8F) + (EEPROM_select << 4)); |
---|
39 | |
---|
40 | return SUCCESS; |
---|
41 | } |
---|
42 | |
---|
43 | // This function checks to see if a valid calibration value is stored on the EEPROM |
---|
44 | // and returns the value if so. |
---|
45 | // baseaddr is the base address of the EEPROM device |
---|
46 | // RxNTx specifies whether the values are the Rx or Tx values. 1 indicates Rx |
---|
47 | // val_select selects which value to write |
---|
48 | // 1: DC offset 2: Gain IQ 3: Phase IQ |
---|
49 | // Returns a short where the most significant byte is the Q-value and |
---|
50 | // the least significant byte is the I-value. |
---|
51 | // Returns 0 if there is no valid data or if the function is called on an EEPROM |
---|
52 | // located on and FPGA board |
---|
53 | short WarpEEPROM_ReadRadioCal(unsigned int* baseaddr, char RxNTx, char val_select) |
---|
54 | { |
---|
55 | Xuint8 memory[8]; |
---|
56 | Xuint16 calval; |
---|
57 | |
---|
58 | // Ensure use of Radio EEPROM |
---|
59 | if(WarpEEPROM_GetDeviceType(baseaddr) != 0x02) |
---|
60 | return FAILURE; |
---|
61 | |
---|
62 | // Get current page from memory. |
---|
63 | WarpEEPROM_ReadMem(baseaddr, 0, RxNTx, memory); |
---|
64 | |
---|
65 | |
---|
66 | if((memory[1] & (1 << val_select)) != 0) // Is the desired calibration value, valid? |
---|
67 | { |
---|
68 | calval = (memory[val_select*2+1] << 8) + memory[val_select*2]; // If so, return the value |
---|
69 | } |
---|
70 | else |
---|
71 | calval = 0; // If not, return 0 |
---|
72 | |
---|
73 | return calval; |
---|
74 | } |
---|
75 | |
---|
76 | // This function writes a calibration value to the EEPROM |
---|
77 | // baseaddr is the base address of the EEPROM device |
---|
78 | // RxNTx specifies whether the values are the Rx or Tx values. 1 indicates Rx |
---|
79 | // val_select selects which value to write |
---|
80 | // 1: DC offset 2: Gain IQ 3: Phase IQ |
---|
81 | // I_val is the I-component to be stored |
---|
82 | // Q_val is the Q-component to be stored |
---|
83 | char WarpEEPROM_WriteRadioCal(unsigned int* baseaddr, char RxNTx, char val_select, char I_val, char Q_val) |
---|
84 | { |
---|
85 | Xuint8 memory[8], success; |
---|
86 | |
---|
87 | // Ensure use of Radio EEPROM |
---|
88 | if(WarpEEPROM_GetDeviceType(baseaddr) != 0x02) |
---|
89 | return FAILURE; |
---|
90 | |
---|
91 | // Get current page and sector from memory |
---|
92 | WarpEEPROM_ReadMem(baseaddr, 0, RxNTx, memory); |
---|
93 | |
---|
94 | |
---|
95 | // Store the I and Q values |
---|
96 | memory[val_select*2] = I_val; |
---|
97 | memory[val_select*2+1] = Q_val; |
---|
98 | |
---|
99 | // Set the valid bit to 1 |
---|
100 | if((memory[1] & (1 << val_select)) == 0) |
---|
101 | memory[1] = memory[1] + (1 << val_select); |
---|
102 | |
---|
103 | // Store the new value back to memory. |
---|
104 | success = WarpEEPROM_WriteMem(baseaddr, 0, RxNTx, memory); |
---|
105 | |
---|
106 | if(success == 0) |
---|
107 | return SUCCESS; |
---|
108 | else |
---|
109 | return FAILURE; |
---|
110 | } |
---|
111 | |
---|
112 | // This function writes a 6-byte MAC address into a 6-byte array addressed by a pointer. |
---|
113 | // baseaddr is the base address of the EEPROM device |
---|
114 | // dev_select specifies which device's MAC address to read |
---|
115 | // 0: FPGA Board 1: Radio1 2: Radio2 3: Radio3 4: Radio4 |
---|
116 | // *MAC is a pointer to a 6-byte array |
---|
117 | // Returns all 1's if there is no valid MAC address |
---|
118 | // NOTE: The Addresses have been mapped on the EEPROM so as to fit on only 1 data page |
---|
119 | void WarpEEPROM_ReadMACAddress(unsigned int* baseaddr, char dev_select, char *MAC) |
---|
120 | { |
---|
121 | Xuint8 memory[8], i; |
---|
122 | |
---|
123 | // Ensure use of FPGA EEPROM |
---|
124 | if(WarpEEPROM_GetDeviceType(baseaddr) != 0x01) |
---|
125 | { |
---|
126 | for(i = 0; i < 6; i++) |
---|
127 | MAC[i] = 0xff; |
---|
128 | return; |
---|
129 | } |
---|
130 | |
---|
131 | // Get the valid register |
---|
132 | WarpEEPROM_ReadMem(baseaddr, 0, 0, memory); |
---|
133 | |
---|
134 | // If there is no valid MAC address stored, return all 1's as the address |
---|
135 | if((memory[1] & (1 << dev_select)) == 0) |
---|
136 | { |
---|
137 | for(i = 0; i < 6; i++) |
---|
138 | MAC[i] = 0xff; |
---|
139 | return; |
---|
140 | } |
---|
141 | |
---|
142 | switch(dev_select) // Choose which device's MAC address is being stored. |
---|
143 | { |
---|
144 | case(0) : // FPGA BOARD |
---|
145 | { |
---|
146 | for(i = 0; i < 6; i++) |
---|
147 | MAC[i] = memory[i+2]; // Write bytes to MAC |
---|
148 | |
---|
149 | break; |
---|
150 | } |
---|
151 | case(1) : // Radio 1 |
---|
152 | { |
---|
153 | WarpEEPROM_ReadMem(baseaddr, 0, 1, memory); // Get Pg0Sec1 |
---|
154 | for(i = 0; i < 6; i++) |
---|
155 | MAC[i] = memory[i]; // Write bytes to MAC |
---|
156 | |
---|
157 | break; |
---|
158 | } |
---|
159 | case(2) : // Radio 2 |
---|
160 | { |
---|
161 | WarpEEPROM_ReadMem(baseaddr, 0, 1, memory); // Get Pg0Sec1 |
---|
162 | for(i = 0; i < 2; i++) |
---|
163 | MAC[i] = memory[i+6]; // Write bytes to MAC |
---|
164 | |
---|
165 | WarpEEPROM_ReadMem(baseaddr, 0, 2, memory); // Get Pg0Sec2 |
---|
166 | for(i = 0; i < 4; i++) |
---|
167 | MAC[i+2] = memory[i]; // Write bytes to MAC |
---|
168 | |
---|
169 | break; |
---|
170 | } |
---|
171 | case(3) : // Radio 3 |
---|
172 | { |
---|
173 | WarpEEPROM_ReadMem(baseaddr, 0, 2, memory); // Get Pg0Sec2 |
---|
174 | for(i = 0; i < 4; i++) |
---|
175 | MAC[i] = memory[i+4]; // Write bytes to MAC |
---|
176 | |
---|
177 | WarpEEPROM_ReadMem(baseaddr, 0, 3, memory); // Get Pg0Sec3 |
---|
178 | for(i = 0; i < 2; i++) |
---|
179 | MAC[i+4] = memory[i]; // Write byte to MAC |
---|
180 | |
---|
181 | break; |
---|
182 | } |
---|
183 | case(4) : // Radio 4 |
---|
184 | { |
---|
185 | WarpEEPROM_ReadMem(baseaddr, 0, 3, memory); // Get Pg0Sec3 |
---|
186 | for(i = 0; i < 6; i++) |
---|
187 | MAC[i] = memory[i+2]; // Write bytes to MAC |
---|
188 | |
---|
189 | break; |
---|
190 | } |
---|
191 | default : // Invalid address return all 1's |
---|
192 | { |
---|
193 | for(i = 0; i < 6; i++) |
---|
194 | MAC[i] = 0xff; |
---|
195 | } |
---|
196 | } |
---|
197 | } |
---|
198 | |
---|
199 | // This function writes a 6-byte MAC address into the EEPROM. |
---|
200 | // baseaddr is the base address of the EEPROM device |
---|
201 | // dev_select specifies which device's MAC address to read |
---|
202 | // 0: FPGA Board 1: Radio1 2: Radio2 3: Radio3 4: Radio4 |
---|
203 | // *MAC is a pointer to a 6-byte array containing the address |
---|
204 | // Returns SUCCESS if all goes well, FAILURE otherwise |
---|
205 | char WarpEEPROM_WriteMACAddress(unsigned int* baseaddr, char dev_select, char *MAC) |
---|
206 | { |
---|
207 | Xuint8 memory[8], i, success; |
---|
208 | |
---|
209 | // Ensure use of the FPGA EEPROM |
---|
210 | if(WarpEEPROM_GetDeviceType(baseaddr) != 0x01) |
---|
211 | return FAILURE; |
---|
212 | |
---|
213 | switch(dev_select) // Choose which device's MAC address to write |
---|
214 | { |
---|
215 | case(0) : // FPGA BOARD |
---|
216 | { |
---|
217 | WarpEEPROM_ReadMem(baseaddr, 0, 0, memory); |
---|
218 | for(i = 0; i < 6; i++) |
---|
219 | memory[i+2] = MAC[i]; // Write bytes to memory sector |
---|
220 | memory[1] = (memory[1] & 0xFE) + 1; // Set valid flag |
---|
221 | |
---|
222 | success = WarpEEPROM_WriteMem(baseaddr, 0 , 0, memory); // Write sector back to mem |
---|
223 | |
---|
224 | if(success == 0) |
---|
225 | return SUCCESS; |
---|
226 | else |
---|
227 | return FAILURE; |
---|
228 | break; |
---|
229 | } |
---|
230 | case(1) : // Radio 1 |
---|
231 | { |
---|
232 | WarpEEPROM_ReadMem(baseaddr, 0, 1, memory); // Get Pg0Sec1 |
---|
233 | for(i = 0; i < 6; i++) |
---|
234 | memory[i] = MAC[i]; // Write bytes to memory sector |
---|
235 | |
---|
236 | success = WarpEEPROM_WriteMem(baseaddr, 0, 1, memory); // Write sector back to mem |
---|
237 | |
---|
238 | break; |
---|
239 | } |
---|
240 | case(2) : // Radio 2 |
---|
241 | { |
---|
242 | WarpEEPROM_ReadMem(baseaddr, 0, 1, memory); // Get Pg0Sec1 |
---|
243 | for(i = 0; i < 2; i++) |
---|
244 | memory[i+6] = MAC[i]; // Write bytes to memory sector |
---|
245 | |
---|
246 | success = WarpEEPROM_WriteMem(baseaddr, 0, 1, memory); // Write the sector back to mem |
---|
247 | |
---|
248 | WarpEEPROM_ReadMem(baseaddr, 0, 2, memory); // Get Pg0Sec2 |
---|
249 | for(i = 0; i < 4; i++) |
---|
250 | memory[i] = MAC[i+2]; // Write bytes to memory sector |
---|
251 | |
---|
252 | success = success + WarpEEPROM_WriteMem(baseaddr, 0, 2, memory); // Write sector back to mem |
---|
253 | |
---|
254 | break; |
---|
255 | } |
---|
256 | case(3) : // Radio 3 |
---|
257 | { |
---|
258 | WarpEEPROM_ReadMem(baseaddr, 0, 2, memory); // Get Pg0Sec2 |
---|
259 | for(i = 0; i < 4; i++) |
---|
260 | memory[i+4] = MAC[i]; // Write bytes to memory sector |
---|
261 | |
---|
262 | success = WarpEEPROM_WriteMem(baseaddr, 0, 2, memory); // Write sector back to mem |
---|
263 | |
---|
264 | WarpEEPROM_ReadMem(baseaddr, 0, 3, memory); // Get Pg0Sec3 |
---|
265 | for(i = 0; i < 2; i++) |
---|
266 | memory[i] = MAC[i+4]; // Write byte to memory sector |
---|
267 | |
---|
268 | success = success + WarpEEPROM_WriteMem(baseaddr, 0, 3, memory); // Write sector back to mem |
---|
269 | |
---|
270 | break; |
---|
271 | } |
---|
272 | case(4) : // Radio 4 |
---|
273 | { |
---|
274 | WarpEEPROM_ReadMem(baseaddr, 0, 3, memory); // Get Pg0Sec3 |
---|
275 | for(i = 0; i < 6; i++) |
---|
276 | memory[i+2] = MAC[i]; // Write bytes to memory sector |
---|
277 | |
---|
278 | success = WarpEEPROM_WriteMem(baseaddr, 0, 3, memory); // Write sector back to mem |
---|
279 | |
---|
280 | break; |
---|
281 | } |
---|
282 | default : // Invalid address return all 1's |
---|
283 | { |
---|
284 | for(i = 0; i < 6; i++) |
---|
285 | MAC[i] = 0xFF; |
---|
286 | } |
---|
287 | } |
---|
288 | |
---|
289 | if(success == 0) |
---|
290 | { |
---|
291 | WarpEEPROM_ReadMem(baseaddr, 0, 0, memory); // Get Pg0Sec0 |
---|
292 | |
---|
293 | // Set the appropriate valid bit |
---|
294 | if((memory[1] & (1 << dev_select)) == 0) |
---|
295 | memory[01] = memory[1] + (1 << dev_select); |
---|
296 | |
---|
297 | success = WarpEEPROM_WriteMem(baseaddr, 0, 0, memory); |
---|
298 | |
---|
299 | if(success == 0) |
---|
300 | return SUCCESS; |
---|
301 | else |
---|
302 | return FAILURE; |
---|
303 | } |
---|
304 | else |
---|
305 | return FAILURE; |
---|
306 | } |
---|
307 | |
---|
308 | // Returns the the 2-byte serial number assigned by Rice WARP |
---|
309 | short WarpEEPROM_ReadWARPSerial(unsigned int* baseaddr) |
---|
310 | { |
---|
311 | Xuint8 memory[8]; |
---|
312 | Xuint16 serial; |
---|
313 | WarpEEPROM_ReadControlBytes(baseaddr, memory); // Store control bytes to memory |
---|
314 | serial = (memory[7] << 8) + memory[6]; // Make short out of two bytes |
---|
315 | return serial; |
---|
316 | } |
---|
317 | |
---|
318 | // Get Serial number from a EEPROM device. Assumes it is the only device on the bus. |
---|
319 | // Assumes previous initialization. |
---|
320 | // baseaddr is the base address of the EEPROM device |
---|
321 | // edits a memory array containing the 1 byte family code, 6 byte serial |
---|
322 | // serial number and 1 byte CRC value |
---|
323 | char WarpEEPROM_ReadDSSerial(unsigned int* baseaddr, unsigned char *Serial) |
---|
324 | { |
---|
325 | Xuint8 check; |
---|
326 | |
---|
327 | // Intialize the EEPROM |
---|
328 | WarpEEPROM_Initialize(baseaddr); |
---|
329 | |
---|
330 | // Send Serial# Command (0x33) to the EEPROM |
---|
331 | WarpEEPROM_WriteByte(baseaddr, 0x33); |
---|
332 | |
---|
333 | // Iterate through 8 bytes of returning data and |
---|
334 | // Store the data to array Serial |
---|
335 | Xuint8 count; |
---|
336 | for(count=0; count<8; count++) |
---|
337 | { |
---|
338 | Serial[count] = WarpEEPROM_ReadByte(baseaddr); |
---|
339 | } |
---|
340 | |
---|
341 | return WarpEEPROM_VerifyROM(Serial); // Return the CRC check result |
---|
342 | } |
---|
343 | |
---|
344 | // This function reads from a specified memory location in the 1024-bit memory. |
---|
345 | // Returns an 8-byte sector of the EEPROM. |
---|
346 | // baseaddr is the base address of the EEPROM device |
---|
347 | // page must be 1-3, and refers to memory pages on the device |
---|
348 | // sector must be 1-3, and refers to the appropriate sector on the device |
---|
349 | // array must be an 8 byte array |
---|
350 | // Returns SUCCESS if no error, otherwise FAILURE |
---|
351 | char WarpEEPROM_ReadUserMem(unsigned int* baseaddr, char page, char sector, unsigned char *array) |
---|
352 | { |
---|
353 | if((page > 3) || (page < 1)) // Verify valid page # |
---|
354 | { |
---|
355 | print("\r\nInvalid Page Number\r\n"); |
---|
356 | return FAILURE; |
---|
357 | } |
---|
358 | else if((sector > 3) || (sector < 1)) // Verify valid sector # |
---|
359 | { |
---|
360 | print("\r\nInvalid Sector Number\r\n"); |
---|
361 | return FAILURE; |
---|
362 | } |
---|
363 | |
---|
364 | Xuint8 check, i; |
---|
365 | |
---|
366 | check = WarpEEPROM_ReadMem(baseaddr, page, sector, array); // Store memory sector to array |
---|
367 | |
---|
368 | for(i = 0; i < 8; i++) |
---|
369 | xil_printf("\r\nByte[%d] : %x", i,array[i]); |
---|
370 | |
---|
371 | if(check == 0) |
---|
372 | return SUCCESS; |
---|
373 | else |
---|
374 | return FAILURE; |
---|
375 | } |
---|
376 | |
---|
377 | // Writes a given 8-byte array to a designated location in memory. |
---|
378 | // Essentially a wrapper of the WriteScratch, ReadScratch and Scratch2Mem functions |
---|
379 | // baseaddr is the base address of the EEPROM device |
---|
380 | // page must be 1-3, and refers to memory pages on the device |
---|
381 | // sector must be 1-3, and refers to the appropriate sector on the device |
---|
382 | // array must be an 8 byte array |
---|
383 | char WarpEEPROM_WriteUserMem(unsigned int* baseaddr, char page, char sector, unsigned char *array) |
---|
384 | { |
---|
385 | if((page > 3) || (page < 1)) // Verify valid page # |
---|
386 | { |
---|
387 | print("\r\nInvalid Page Number\r\n"); |
---|
388 | return FAILURE; |
---|
389 | } |
---|
390 | else if((sector > 3) || (sector < 1)) // Verify valid sector # |
---|
391 | { |
---|
392 | print("\r\nInvalid Sector Number\r\n"); |
---|
393 | return FAILURE; |
---|
394 | } |
---|
395 | |
---|
396 | Xuint8 check, i; |
---|
397 | |
---|
398 | check = WarpEEPROM_WriteMem(baseaddr, page, sector, array); // Write array to memory sector |
---|
399 | if(check == 0) |
---|
400 | return SUCCESS; |
---|
401 | else |
---|
402 | return FAILURE; |
---|
403 | } |
---|