[1166] | 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 | } |
---|