WARP Radio Board TX DC Offset Calibration
The radio transceiver on the WARP Radio Board uses a direct conversion architecture. One side-effect of this is a sensitivity to DC offsets in the transmitted signal. Any DC component in the transmit waveform results in carrier leakage at RF. In addition to any DC component in the user's transmitted waveform, the radio board itself introduces a small DC offset due to variations in component values and board assembly.
To avoid these problems, users should be careful to transmit waveforms with zero DC component, and should calibrate their radios. Follow the steps below to calibrate a WARP Radio Board.
Calibrating a Radio
The residual DC offset due to component variations can be estimated using a special calibration mode of the radio board. During calibration, the algorithm estimates DC offsets for the I and Q channels on a given radio board. These values are then stored to the radio board's EEPROM. Once stored, the DC calibration values can be read by user applications each time the board is used.
Radio Calibration
Every WARP Radio is calibrated before shipment. You can re-calibrate your radios if desired, using this procedure.
The Tx DCO calibration algorithm is not publically available. However, we do distribute an FPGA configuration file which executes the calibration process automatically. This is the same program we use internally to calibrate new radio boards.
- This program requires a serial terminal connected to your FPGA board. Configure the termianl for 9600bps (FPGA v1) or 57600bps (FPGA v2).
- Download a copy of this configuraiton file:
WARP v1 (XC2VP70 FPGA): WARP_Radio_TxDCO_Calibrate_FPGAv1.bit
WARP v2 (XC4VFX100 FPGA): WARP_Radio_TxDCO_Calibrate_FPGAv2.bit - You will see this menu:
********** WARP Radio Calibration - Main Menu ********** Please select a radio to test: (1) Radio in Slot #1 (2) Radio in Slot #2 (3) Radio in Slot #3 (4) Radio in Slot #4
- Select which radio to calibrate by typing a digit. The radio number corresponds to the daughtercard slot where it is mounted. By default, WARP MIMO kits have radios in slots 2 and 3.
- You will then see this menu; each of these options is explained below:
Please select a test: (0) EEPROM Current Contents (1) EEPROM Initialization (2) Tx DC Offset Calibration (q) Return to radio selection
EEPROM Current Contents
The radio board's EEPROM is initiailzed before shipment. By default, it is programmed with the board's version information (version 1, revision 4), serial number and initial Tx DCO values. The EEPROM Current Contents option will read these values from the EERPOM and display them. You will see something like this:
EEPROM Values for Radio Board in Slot 2 WARP Radio Board Version 1.4 Serial Number (WARP): WR-a-00083 EEPROM Hard-wired Serial Number: 0 0 0 46 59 C1 Current TxDCO Values: I: 148 Q: 34
EEPROM Initialization
The radio board's EEPROM must be initialized before it can be used to store calibration values. We initialize every EEPROM before shipping a kit. You can re-initialize the EERPOM using this option. You will see these prompts:
Welcome to the WARP Radio EEPROM Initial Setup RADIO BOARD 2 SETUP Please enter the radio board's version number (1-7): 1 Please enter the radio board's revision number (0-7): 4 Please enter the five digit serial number: WR-a-00083
For the version number, enter 1. For the revision number, enter 4. For the serial number, enter the five digits printed on your radio board's serial number label, including leading zeros.
The program will then print the EEPROM contents. If the displayed values match your entries, the EEPROM initialization was successful.
EEPROM Values for Radio Board in Slot 2 WARP Radio Board Version 1.4 Serial Number (WARP): WR-a-00083 EEPROM Hard-wired Serial Number: 0 0 0 46 59 C1 Current TxDCO Values: I: 148 Q: 34
Tx DC Offset Calibration
The TxDCO calibration routine is automatic. Once started, the program will run for a few seconds, then display the following:
*************Tx DC Offset Calibration************* Calibrating radio in slot 2: Radio #2 calibration starting...done Applying best DC Offsets... Radio #2: Best I: 146, Best Q: 34 EEPROM Successfully Updated with DC Offset Values. EEPROM Readback: I: 146 Q: 34 Now accepting manual input Type [a,q,s,w] for I-/I+/Q-/Q+ DC offset adjustment Type [e,d] to enable/disable the transmitter Type r to record the updated I/Q offset values to the EEPROM Type q to return to the main menu
If the EEPROM Readback: values match the Radio #X: Best values, the calibration and EEPROM writing processes were successful.
Using Calibration Values
User applications should use the stored Tx DCO calibration values on power-up. The code below is an example of how this is done. This function is portable and should compile when integrated with a user application in XPS.
//Assumes your hardware platform contains: // radio_controller_v1_08_a or later // EEPROM_v1_00_a or EEPROM_v1_01_a //Before calling this function, your application must initialize // the radio controller using the WarpRadio_v1_Reset() function //Your code must also include: // #include radio_prototypes.h /* from the radio_controller driver */ // #include EEPROM.h /* from the EEPROM driver */ void CalibrateTxDCO () { unsigned char i; unsigned int thisRadio; int eepromStatus = 0; short calReadback = 0; signed short best_I, best_Q; //Select which radios should be used // Include RADION_ADDR to enable a radio, 0 to disable it // This array must contain 4 elements corresponding to the 4 radios // Use a value of RADION_ADDR (for N=[1,2,3,4]) to enable a radio // Use 0 to disable a radio // For example, these arrys are valid: // {RADIO1_ADDR, RADIO2_ADDR, RADIO3_ADDR, RADIO4_ADDR} //Calibrate all four radios // {RADIO1_ADDR, 0, 0, RADIO4_ADDR} //Calibrate radios #1 and #4 // But these are not: // {RADIO2_ADDR, RADIO1_ADDR, 0, 0} //Out of order // {RADIO1_ADDR} //Not enough elements unsigned int selectedRadios[4] = {0, RADIO2_ADDR, RADIO3_ADDR, 0}; for(i=0; i<4; i++) { thisRadio = selectedRadios[i]; //Only read values for enabled radios if(thisRadio > 0) { //Select the EEPROM on the current radio board eepromStatus = WarpEEPROM_EEPROMSelect((unsigned int*)XPAR_EEPROM_0_BASEADDR, i+1); //Initialize the EEPROM controller eepromStatus = WarpEEPROM_Initialize((unsigned int*)XPAR_EEPROM_0_BASEADDR); //Read the Tx DCO values calReadback = WarpEEPROM_ReadRadioCal((unsigned int*)XPAR_EEPROM_0_BASEADDR, 2, 1); //Scale the stored values best_I = (signed short)(((signed char)(calReadback & 0xFF))<<1); best_Q = (signed short)(((signed char)((calReadback>>8) & 0xFF))<<1); //Optional debug output; useful to check whether the values are valid xil_printf("\r\nRadio #%d TxDCO - I: %d Q: %d\r\n", i+1, best_I, best_Q); //Finally, write the Tx DCO values to the DAC WarpRadio_v1_DACOffsetAdj(ICHAN, best_I, thisRadio); WarpRadio_v1_DACOffsetAdj(QCHAN, best_Q, thisRadio); } } return; }