1 | /*! \file warpphy.c |
---|
2 | \brief Provide PHY-specific functions for interfacing WARPMAC (and MAC code) to the OFDM PHY peripherals |
---|
3 | |
---|
4 | @version 15.22 |
---|
5 | @author Chris Hunter & Patrick Murphy |
---|
6 | |
---|
7 | Many of the register names and bit assignments in this file depend on the design of the OFDM PHY. You must |
---|
8 | use matching versions of WARPMAC, WARPPHY and ofdm_txrx_mimo. Refer to the wireless reference designs for |
---|
9 | known-good combinations of versions. |
---|
10 | */ |
---|
11 | |
---|
12 | //XPS-generated header with peripheral parameters |
---|
13 | #include "warp_fpga_board.h" |
---|
14 | #include "xparameters.h" |
---|
15 | |
---|
16 | //Header for WARPPHY Interface |
---|
17 | #include "warpphy.h" |
---|
18 | |
---|
19 | //Header for WARPMAC framework (required for some global values) |
---|
20 | #include "warpmac.h" |
---|
21 | |
---|
22 | // These header files define some macros for reading/writing registers in the Sysgen-designed cores |
---|
23 | // This layer of macros keep this code independent from the name of the sysgen core |
---|
24 | // (sysgen defines its register names as a function of the .mdl file name) |
---|
25 | #include "util/ofdm_txrx_mimo_regMacros.h" |
---|
26 | #include "util/ofdm_agc_mimo_regMacros.h" |
---|
27 | #include "util/warp_timer_regMacros.h" |
---|
28 | #include "util/warp_userio.h" |
---|
29 | |
---|
30 | //Headers for other WARP peripheral cores |
---|
31 | #include "EEPROM.h" |
---|
32 | #include "radio_controller_basic.h" |
---|
33 | #include "radio_controller_ext.h" |
---|
34 | #include "radio_controller_adv.h" |
---|
35 | #include "radio_controller_5ghz.h" |
---|
36 | |
---|
37 | //Other standard header files |
---|
38 | #include <sleep.h> |
---|
39 | #include <stdio.h> |
---|
40 | #include <string.h> |
---|
41 | |
---|
42 | //********Globals******** |
---|
43 | int agc_targetRxPowerOut; |
---|
44 | int agc_noisePowerEstimate; |
---|
45 | |
---|
46 | unsigned char baseRateMod; |
---|
47 | unsigned int numTrainingSyms; |
---|
48 | unsigned int ofdmRx_pktDetDly; |
---|
49 | unsigned int numBaseRate; |
---|
50 | unsigned char txGain; |
---|
51 | unsigned char RxSoftDecodingEn; |
---|
52 | unsigned short pktDet_corrCounterLoad; |
---|
53 | unsigned char pktDet_corrWindowStart; |
---|
54 | unsigned char pktDet_corrWindowEnd; |
---|
55 | |
---|
56 | unsigned int pktDet_energyThresh; |
---|
57 | unsigned int pktDet_carrierSenseThresh; |
---|
58 | unsigned char pktDet_threshMinDur; |
---|
59 | |
---|
60 | unsigned int warpphy_txAntMode; |
---|
61 | unsigned int warpphy_rxAntMode; |
---|
62 | unsigned int activeRadios_Tx, activeRadios_Rx; |
---|
63 | unsigned int activePHYStatusBits; |
---|
64 | unsigned short longCorrThresh; |
---|
65 | unsigned int afScaling; |
---|
66 | |
---|
67 | unsigned short pktDetCFOsampCount; |
---|
68 | |
---|
69 | unsigned int RxFFT_Window_Offset; |
---|
70 | unsigned int txScaling_preamble; |
---|
71 | unsigned int txScaling_payload; |
---|
72 | |
---|
73 | unsigned int agcIIR_g, agcIIR_fb; |
---|
74 | |
---|
75 | |
---|
76 | ///////////////////////////////// |
---|
77 | |
---|
78 | ///@brief Initializes the OFDM PHY core |
---|
79 | ///The OFDM PHY and radio controller cores have many options which must be configured before they can |
---|
80 | ///be used over the air. This funciton configures these cores with sensible defaults. |
---|
81 | int warpphy_init(){ |
---|
82 | unsigned int i; |
---|
83 | xil_printf(" Initializing WARPPHY:\r\n"); |
---|
84 | |
---|
85 | //Set the default antenna configuration |
---|
86 | warpphy_txAntMode = TX_ANTMODE_SISO_ANTA; |
---|
87 | warpphy_rxAntMode = RX_ANTMODE_SISO_ANTA; |
---|
88 | activePHYStatusBits = DEFAULT_STATUSBITS; |
---|
89 | |
---|
90 | //Hold the PHY in reset until everything it setup; the reset does not initialize the PHY's registers |
---|
91 | mimo_ofdmTx_disable(); |
---|
92 | mimo_ofdmRx_disable(); |
---|
93 | |
---|
94 | //Initialize global variables |
---|
95 | longCorrThresh = 9000;//3500; //2750 |
---|
96 | |
---|
97 | afScaling = 2944;//6656; |
---|
98 | |
---|
99 | //AGC target output power, in units of dBv (voltage at MAX2829 output) |
---|
100 | agc_targetRxPowerOut = -12; |
---|
101 | |
---|
102 | //AGC noise power estimate, in dBm |
---|
103 | agc_noisePowerEstimate = -95; |
---|
104 | |
---|
105 | //Base-rate modulation scheme; should be QPSK |
---|
106 | baseRateMod = QPSK; |
---|
107 | |
---|
108 | //Number of training symbol periods (all on 1 antenna for SISO, split across antennas for MIMO) |
---|
109 | numTrainingSyms = NUM_TRAINING_SYMBOLS; |
---|
110 | |
---|
111 | //Number of base rate OFDM symbols; every node must agree on this number ahead of time |
---|
112 | // IF FEC is enabled, the base rate symbols are always encoded at rate 1/2, so a 24-byte |
---|
113 | // header at QPSK occupies 4 symbols (instead of 2 when uncoded) |
---|
114 | numBaseRate = NUM_BASERATE_SYMBOLS; |
---|
115 | |
---|
116 | //Packet detection delay, in sys_clk cycles |
---|
117 | // The Rx PHY waits this long before searching for correlation peaks |
---|
118 | ofdmRx_pktDetDly = 124; |
---|
119 | |
---|
120 | //Tx RF gain (6-bit value in [0,63]) |
---|
121 | txGain = 0x3f; |
---|
122 | |
---|
123 | //Tx scaling values; both are interpreted as UFix16_13 values |
---|
124 | // The ratio of preamble/payload values should be approx 1/4 |
---|
125 | // Increasing these values will increase Tx power at the expense of clipping |
---|
126 | txScaling_preamble = 3072; |
---|
127 | txScaling_payload = 12288; |
---|
128 | |
---|
129 | //Packet detector parameters |
---|
130 | // Energy threshold - X/16 = RSSI |
---|
131 | pktDet_energyThresh = 8000; |
---|
132 | |
---|
133 | //Carrier sensing threshold - 8192/16 = RSSI of 512 (approx -65dBm Rx power) |
---|
134 | pktDet_carrierSenseThresh = 8192; |
---|
135 | |
---|
136 | //Minimum duration of energy-above-energyThresh required to assert a packet detection |
---|
137 | pktDet_threshMinDur = 24; |
---|
138 | |
---|
139 | //Define the FFT start offset (FFT will use (15 - offset) samples of cyclic prefix to handle synchronization |
---|
140 | RxFFT_Window_Offset = INIT_RXFFTOFSET; |
---|
141 | |
---|
142 | //Set some magic numbers for the CFO correction calculations; these are only used for pre-correcting CFO in DF mode |
---|
143 | warpphy_setPilotCFOCorrection(0x8025AEE6); |
---|
144 | warpphy_setCoarseCFOCorrection(30533); |
---|
145 | |
---|
146 | /*****************Radio Setup******************/ |
---|
147 | xil_printf("\tInitializing Radio Transmitter...\r\n"); |
---|
148 | |
---|
149 | //The second argument sets the clock ratio in the radio controller's SPI controller |
---|
150 | // 1 is good for a 40MHz bus |
---|
151 | // 2 is the right value for an 80MHz bus |
---|
152 | WarpRadio_v1_Reset((unsigned int *)XPAR_RADIO_CONTROLLER_0_BASEADDR, 1); |
---|
153 | |
---|
154 | xil_printf("\tStarting TxDCO correction...\r\n"); |
---|
155 | |
---|
156 | //Apply the stored TX DC offset correction values for each radio |
---|
157 | warpphy_applyTxDCOCalibration(FIRST_RADIO); |
---|
158 | warpphy_applyTxDCOCalibration(SECOND_RADIO); |
---|
159 | |
---|
160 | //Configure some MAX2829 Tx parameters for good wideband performance |
---|
161 | |
---|
162 | //Disable software control of the TxEn/RxEn signals; the PHY will control these |
---|
163 | WarpRadio_v1_RxEnSoftControlDisable(BOTH_RADIOS); |
---|
164 | WarpRadio_v1_TxEnSoftControlDisable(BOTH_RADIOS); |
---|
165 | |
---|
166 | //Set Tx bandwidth - 0x1 = 24MHz (minimum) |
---|
167 | WarpRadio_v1_TxLpfCornFreqCoarseAdj(0x1, BOTH_RADIOS); |
---|
168 | |
---|
169 | //Enable hardware control of Tx gains (handled by the radio controller Tx state machine) |
---|
170 | WarpRadio_v1_SoftwareTxGainControl(0, BOTH_RADIOS); |
---|
171 | |
---|
172 | //Four arguments: dly_TxEn, dly_TxStart, dly_GainRampEn, dly_PowerAmpEn, each in units of bus clock cycles |
---|
173 | WarpRadio_v1_SetTxTiming(BOTH_RADIOS, 0, 200, 100, 0); |
---|
174 | |
---|
175 | //Three arguments: targetGain, gainStep, stepInterval; max targetGain is 0x3F |
---|
176 | WarpRadio_v1_SetTxGainTiming(BOTH_RADIOS, txGain, 0xF, 1); |
---|
177 | |
---|
178 | //Set the MAX2829 Tx baseband gain; 0x3 is max gain |
---|
179 | WarpRadio_v1_BaseBandTxGain(0x3, BOTH_RADIOS); |
---|
180 | |
---|
181 | xil_printf("\tInitializing Radio Receiver..."); |
---|
182 | |
---|
183 | //Enable hardware AGC control of receive gains & RxHP |
---|
184 | WarpRadio_v1_RxHpSoftControlDisable(BOTH_RADIOS); |
---|
185 | WarpRadio_v1_SoftwareRxGainControl(0, BOTH_RADIOS); |
---|
186 | |
---|
187 | //Set bandwith with RxHP=0; RxHighPassCornerFreq(0) is critical for good performance |
---|
188 | WarpRadio_v1_RxHighPassCornerFreq(0, BOTH_RADIOS); |
---|
189 | |
---|
190 | //Set Rx bandwidth; 0x0 = 15MHz (minimum) |
---|
191 | WarpRadio_v1_RxLpfCornFreqCoarseAdj(0, BOTH_RADIOS); |
---|
192 | |
---|
193 | xil_printf("complete!\r\n"); |
---|
194 | /**********************************************************/ |
---|
195 | |
---|
196 | /*******************Packet Detector************************/ |
---|
197 | xil_printf("\tInitializing Packet Detection..."); |
---|
198 | |
---|
199 | //Assert the packet detection output reset |
---|
200 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_ignoreDet(1); |
---|
201 | |
---|
202 | //Set the RSSI clock ratio; 0=sys_clk/4; 1=sys_clk/8 |
---|
203 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setRSSIclkRatio(0); |
---|
204 | |
---|
205 | //Set the minimum energy duration |
---|
206 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setMinDuration(pktDet_threshMinDur); |
---|
207 | |
---|
208 | //Enable the carrier-sensing block's IDLE output (the timer can choose to use or ignore it) |
---|
209 | ofdm_txrx_mimo_WriteReg_Rx_CSMA_enableIdle(1); |
---|
210 | |
---|
211 | //Hold the packet detector's running sum in reset |
---|
212 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_resetSum(1); |
---|
213 | |
---|
214 | //Configure the packet detector's antenna masks (1=antA, 2=antB, 3=both) |
---|
215 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setMask(PKTDET_MASK_ANTA); |
---|
216 | |
---|
217 | //Set the packet detector's logic mode for the two antenna ports; 0 = AND, 1 = OR |
---|
218 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setMode(1); |
---|
219 | |
---|
220 | //Set the running sum length; 16 is a good default |
---|
221 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setAvgLen(PKTDET_RSSI_SUMLEN); |
---|
222 | |
---|
223 | //Set the detector's energy threshold; this value must be scaled relative to the sum-length |
---|
224 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setThresh(pktDet_energyThresh); |
---|
225 | |
---|
226 | //Set the carrier sensing threshold to a very high level, disabling it by default |
---|
227 | ofdm_txrx_mimo_WriteReg_Rx_CSMA_setThresh(CSMA_DISABLED_THRESH); |
---|
228 | |
---|
229 | //Set the DIFS period; this is the require IDLE time before the IDLE output will assert |
---|
230 | // Units are sys_clk/4 cycles (10MHz), so 300 = 30us |
---|
231 | // This delay must exceed the TxDATA->TxACK turn around time (currently 23us) |
---|
232 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setDIFSPeriod(300); |
---|
233 | |
---|
234 | //Deassert the running sum reset; the sum will run continuously after this |
---|
235 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_resetSum(0); |
---|
236 | |
---|
237 | //Set thresholds for the autoCorrelation detector |
---|
238 | //CorrThresh (UFix8_7): 0.7 ≈ 90 |
---|
239 | //MinPoiwer (UFix12_0); 2048 is theoretical max, 100-300 is more realistic, 0 works too |
---|
240 | ofdm_txrx_mimo_WriteReg_Rx_PktDetCorr_params(90, 0); |
---|
241 | |
---|
242 | //Enable both the RSSI and autoCorrelation packet detectors |
---|
243 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_rssiDetEn(1); |
---|
244 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_corrDetEn(1); |
---|
245 | |
---|
246 | //Deassert the packet detection output reset; packet detection events will start after this |
---|
247 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_ignoreDet(0); |
---|
248 | |
---|
249 | xil_printf("complete!\r\n"); |
---|
250 | /**********************************************************/ |
---|
251 | |
---|
252 | /*************************PHY******************************/ |
---|
253 | |
---|
254 | xil_printf("\tInitializing OFDM Transmitter..."); |
---|
255 | |
---|
256 | //Clear all the match and action blocks in the auto response system |
---|
257 | mimo_ofdmTxRx_setAction0(0); |
---|
258 | mimo_ofdmTxRx_setAction1(0); |
---|
259 | mimo_ofdmTxRx_setAction2(0); |
---|
260 | mimo_ofdmTxRx_setAction3(0); |
---|
261 | mimo_ofdmTxRx_setAction4(0); |
---|
262 | mimo_ofdmTxRx_setAction5(0); |
---|
263 | mimo_ofdmTxRx_setMatch0(0); |
---|
264 | mimo_ofdmTxRx_setMatch1(0); |
---|
265 | mimo_ofdmTxRx_setMatch2(0); |
---|
266 | mimo_ofdmTxRx_setMatch3(0); |
---|
267 | mimo_ofdmTxRx_setMatch4(0); |
---|
268 | mimo_ofdmTxRx_setMatch5(0); |
---|
269 | |
---|
270 | //Fill in the header translator with non-translating values by default |
---|
271 | // This will "overwrite" the header with the same pktbuf/byte combos as the template buffer |
---|
272 | // User code will override some entries here to implement a protocol |
---|
273 | for(i=0; i<(32*32); i++) |
---|
274 | { |
---|
275 | //Each entry is a 10-bit number of {srcBuf[4:0], srcByteAddr[4:0]} |
---|
276 | XIo_Out32(XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_TXHEADERTRANSLATE+i*sizeof(int), (i & 0x3FF)); |
---|
277 | } |
---|
278 | |
---|
279 | //Set the AF scaling |
---|
280 | mimo_ofdmRx_setAFTxScaling(afScaling); |
---|
281 | |
---|
282 | //Set the minimum magnitude for channels to use their pilots |
---|
283 | mimo_ofdmRx_setPilotCalcParams(0xFFF); //MinMag as UFix12_12 (41 ~= 0.01) |
---|
284 | |
---|
285 | //Configure the FFT scaling values in the PHY Tx and Rx |
---|
286 | // 6-bits each, 6LSB are Tx scaling; 6LSB+6 are Rx scaling |
---|
287 | mimo_ofdmTxRx_setFFTScaling((unsigned int)(( |
---|
288 | (16*RX_FFT_SCALING_STAGE1 + 4*RX_FFT_SCALING_STAGE2 + 1*RX_FFT_SCALING_STAGE3)<<6 ) | |
---|
289 | (16*TX_FFT_SCALING_STAGE1 + 4*TX_FFT_SCALING_STAGE2 + 1*TX_FFT_SCALING_STAGE3))); |
---|
290 | |
---|
291 | //Subcarrier indicies for pilot tones - the values here must line up with zeros in the modulation setup for each subcarrier |
---|
292 | // Subcarriers [-21,-7,7,21] are the default, matching the 802.11a spec |
---|
293 | mimo_ofdmTx_setPilotIndcies((7 + ((64-21)<<8) + ((64-7)<<16) + ((21)<<24) )); |
---|
294 | |
---|
295 | //Pilot tone values are Fix16_15, so |
---|
296 | // Pilot 1 should be negative, pilot 2 should be positive |
---|
297 | // 0x7FFF is +1, 0x8000 is -1 |
---|
298 | // 0xA57D is ~-0.707, 0x5A82 is ~+0.707 |
---|
299 | mimo_ofdmTxRx_setPilotValues( (0xA57D) + (0x5A82 << 16)); |
---|
300 | |
---|
301 | //2 values in this write: number of training symbols and number of base rate symbols |
---|
302 | // The Tx/Rx nodes must agree on these values ahead of time |
---|
303 | warpphy_setTxNumSyms(numBaseRate, numTrainingSyms); |
---|
304 | warpphy_setRxNumSyms(numBaseRate, numTrainingSyms); |
---|
305 | |
---|
306 | //Scaling constant for the transmitted preamble; helps normalize the amplitude of the stored preamble and actual IFFT output |
---|
307 | mimo_ofdmTx_setTxScaling(txScaling_preamble, txScaling_payload); |
---|
308 | |
---|
309 | //Configure various options in the Tx PHY |
---|
310 | mimo_ofdmTx_setControlBits ( |
---|
311 | (3 << 4) | //Preamble shift for antenna B |
---|
312 | ((0&0x3F) << 20) | //Cyclic shift |
---|
313 | TX_PILOT_SCRAMBLING | //Pseudo-random scrambling of pilot tones |
---|
314 | TX_SOFTWARE_TXEN | //Use the PHY TxStart register to start the overall PHY/radio Tx state machine |
---|
315 | //TX_RANDOM_PAYLOAD | //Use random payload bytes (user must still provide valid header!) |
---|
316 | //TX_ALWAYS_USE_PRECFO | //Always apply Tx CFO, even if the packet isn't triggered by auto responders |
---|
317 | //TX_DISABLE_ANTB_PREAMBLE | //Disables preamble on antenna B |
---|
318 | 0 |
---|
319 | ); |
---|
320 | |
---|
321 | //Shift antenna B preambles by -3 samples |
---|
322 | warpphy_setAntBPreambleShift(13); |
---|
323 | |
---|
324 | xil_printf("complete!\r\n"); |
---|
325 | |
---|
326 | xil_printf("\tInitializing OFDM Receiver..."); |
---|
327 | |
---|
328 | //Configure the FEC blocks |
---|
329 | // (CodingEn, SoftDecodingEn, ZeroTailEn, QPSK_Scaling, 16QAM_Scaling) |
---|
330 | mimo_ofdmTxRx_setFECoptions(1, 1, 0, 6, 16); |
---|
331 | |
---|
332 | //Configures the default number of samples of the cyclic prefix to use for synchronization offset tolerance |
---|
333 | // Larger values here reduce multipath tolerance |
---|
334 | mimo_ofdmRx_setFFTWindowOffset(INIT_RXFFTOFSET); |
---|
335 | |
---|
336 | //Scaling value is a 32-bit value, composed of two UFix16_11 values |
---|
337 | // So 0x08000800 scales A/B by exactly 1 |
---|
338 | // This value is dependent on the number of training symbols |
---|
339 | // For SISO mode and numTraining=2, use 0x10001000 (the default) |
---|
340 | mimo_ofdmRx_setRxScaling(0x10001000); |
---|
341 | |
---|
342 | //Long correlator parameters (for packet detection confirmation and symbol timing) |
---|
343 | // Top 16-bits are long-correlation threshold; 3000 works well over-the-air |
---|
344 | // Bottom 16-bits are sample index corresponding to the long correlation event |
---|
345 | // (basically a magic number that aligns the Rx PHY state machine with the incoming packet) |
---|
346 | |
---|
347 | warpphy_setLongCorrThresh(longCorrThresh); |
---|
348 | |
---|
349 | //The correlator only accepts peaks inside a window relative to the energy detection event |
---|
350 | // Adjust the Start/End values below to grow/shrink the window as needed |
---|
351 | pktDet_corrWindowStart = 90-32; |
---|
352 | pktDet_corrWindowEnd = 180+32; |
---|
353 | |
---|
354 | pktDet_corrCounterLoad = 251;//232; |
---|
355 | pktDetCFOsampCount = 255; |
---|
356 | mimo_ofdmRx_setLongCorrParams(((pktDet_corrCounterLoad & 0x00FF) << 0 ) | \ |
---|
357 | ((pktDetCFOsampCount & 0x00FF) << 8 ) | \ |
---|
358 | ((pktDet_corrWindowStart & 0xFF) << 16 ) | \ |
---|
359 | ((pktDet_corrWindowEnd & 0xFF) << 24 )); //corr window start/end |
---|
360 | |
---|
361 | //Sets the delay between the pkt detection assertion and the PHY searching for correlation peaks |
---|
362 | mimo_ofdmRx_setPktDetDly(ofdmRx_pktDetDly); |
---|
363 | mimo_ofdmRx_setCFOCalcDly(0); |
---|
364 | mimo_ofdmRx_setCFOMaxDiff(255); //UFix8_8 - 0.15 * 256 ≈ 38 |
---|
365 | |
---|
366 | warpphy_setPreCFOoptions( (PRECFO_USECOARSE | PRECFO_USEPILOTS) ); |
---|
367 | |
---|
368 | //Bottom 8 bits are the number of header bytes per packet; nodes must agree on this at build time |
---|
369 | // bits[7:0]: number of header bytes (bytes in base-rate symbols) |
---|
370 | //Three more 8-bit values are stored here - each is an index of a byte in the header: |
---|
371 | // bits[15:8]: less-significant byte of pkt length |
---|
372 | // bits[23:16]: more-significant byte of pkt length |
---|
373 | // bits[31:24]: dynamic modulation masks |
---|
374 | // mimo_ofdmRx_setByteNums( (unsigned int)(NUM_HEADER_BYTES + (2<<8) + (3<<16) + (0<<24) )); |
---|
375 | mimo_ofdmRx_setByteNums( (unsigned int)(NUM_HEADER_BYTES + (3<<8) + (2<<16) + (0<<24) )); |
---|
376 | |
---|
377 | //Configure some sane defaults in the Rx PHY |
---|
378 | mimo_ofdmRx_setOptions |
---|
379 | ( |
---|
380 | RESET_BER | //Hold the BER meter in reset |
---|
381 | REQ_LONG_CORR | //Require long correlation for packet detection |
---|
382 | //RSSI_GAIN_ADJ | //Compensate RSSI input to pkt detector for RF gain changes |
---|
383 | //BYPASS_CARR_REC | //Hold the Rx DDS in reset (ignoring any coarse CFO estimate) |
---|
384 | COARSE_CFO_EN | //Enable coarse CFO estimation |
---|
385 | TX_DISABLE_PKTDET | //Ignore packet detection during Tx |
---|
386 | SIMPLE_DYN_MOD_EN | //Use the header's fullRate field for demodulation |
---|
387 | RESET_ON_BAD_HDR | //Reset Rx PHY if header fails CRC |
---|
388 | RECORD_CHAN_ESTS | //Enable the channel estimate recording buffer |
---|
389 | RECORD_CHAN_ESTMAGS | //Enable the channel estimate recording buffer |
---|
390 | //CHANMAG_MASKING_EN | //Enable channel magnitude masking |
---|
391 | 0, |
---|
392 | activePHYStatusBits |
---|
393 | ); |
---|
394 | |
---|
395 | //Set the modulation masks to sane defaults |
---|
396 | // 0xF enables dynamic modulation for that path |
---|
397 | warpphy_set_modulation(baseRateMod, 0xF, 0xF, 0xF, 0xF); |
---|
398 | |
---|
399 | //Set the antenna modes to SISO by default |
---|
400 | warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA); |
---|
401 | |
---|
402 | warpphy_setNumTrainingSyms(NUM_TRAINING_SYMBOLS); |
---|
403 | |
---|
404 | //Set min chanest magnitudes (UFix16_15 values; set to zero to effectively disable) |
---|
405 | warpphy_setChanEstMinMags(0); |
---|
406 | |
---|
407 | //Set AF blanking interval (set to zeros to disable) |
---|
408 | warpphy_setAFblanking(0, 0); |
---|
409 | |
---|
410 | XIo_Out32(XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_RX_FIXEDPKTLEN, 0); |
---|
411 | |
---|
412 | xil_printf("complete!\r\n"); |
---|
413 | /**********************************************************/ |
---|
414 | |
---|
415 | /***************************AGC****************************/ |
---|
416 | xil_printf("\tInitializing AGC..."); |
---|
417 | //agcIIR_fb = 0x20990; //20kHz cutoff, Fix18_17 |
---|
418 | //agcIIR_g = 0x1fb38; //20kHz cutoff, UFix18_17 |
---|
419 | agcIIR_fb = 0x20000; //0kHz cutoff, Fix18_17 |
---|
420 | agcIIR_g = 0x20000; //0kHz cutoff, UFix18_17 |
---|
421 | ofdm_AGC_Initialize(agc_noisePowerEstimate); |
---|
422 | ofdm_AGC_setNoiseEstimate(agc_noisePowerEstimate); |
---|
423 | |
---|
424 | ofdm_AGC_SetDCO(0x6); //enable both subtraction and IIR filter |
---|
425 | |
---|
426 | ofdm_AGC_SetTarget(agc_targetRxPowerOut); |
---|
427 | ofdm_AGC_Reset(); |
---|
428 | |
---|
429 | XIo_Out32(XPAR_OFDM_AGC_MIMO_PLBW_0_MEMMAP_DCO_IIR_COEF_FB, agcIIR_fb); |
---|
430 | XIo_Out32(XPAR_OFDM_AGC_MIMO_PLBW_0_MEMMAP_DCO_IIR_COEF_GAIN, agcIIR_g); |
---|
431 | |
---|
432 | xil_printf("complete!\r\n"); |
---|
433 | /**********************************************************/ |
---|
434 | |
---|
435 | /**************************Timer***************************/ |
---|
436 | //Initialize the timer hardware; the individual timers will get setup in WARPMAC |
---|
437 | warp_timer_init(); |
---|
438 | /**********************************************************/ |
---|
439 | |
---|
440 | //Finally enable the PHY |
---|
441 | mimo_ofdmTx_enable(); |
---|
442 | mimo_ofdmRx_enable(); |
---|
443 | |
---|
444 | return 0; |
---|
445 | } |
---|
446 | |
---|
447 | ///@brief Clears any pending Rx pkt status in the PHY. Was warpphy_pktAck() in previous versions. |
---|
448 | /// |
---|
449 | ///The Rx PHY blocks after asserting either its good or bad packet status bits. The bits |
---|
450 | ///are cleared by asserting then de-asserting a register bit per status bit. This funciton clears |
---|
451 | ///both good and bad pkt bits; there is no harm in clearing a status bit that isn't actually asserted. |
---|
452 | void warpphy_clearRxPktStatus(){ |
---|
453 | |
---|
454 | //The TxRx_Interrupt_PktBuf_Ctrl register has many bits. |
---|
455 | // bits[2:0] are the Rx status enables |
---|
456 | // bits[6:4] are the Rx status resets |
---|
457 | // bit[3] and bit[7] are used for the TxDone status and are preserved here |
---|
458 | ofdm_txrx_mimo_WriteReg_TxRx_Interrupt_PktBuf_Ctrl(OFDM_BASEADDR, ofdm_txrx_mimo_ReadReg_TxRx_Interrupt_PktBuf_Ctrl(OFDM_BASEADDR) | DEFAULT_STATUSBITRESETS); |
---|
459 | ofdm_txrx_mimo_WriteReg_TxRx_Interrupt_PktBuf_Ctrl(OFDM_BASEADDR, ofdm_txrx_mimo_ReadReg_TxRx_Interrupt_PktBuf_Ctrl(OFDM_BASEADDR) & ~DEFAULT_STATUSBITRESETS); |
---|
460 | |
---|
461 | return; |
---|
462 | } |
---|
463 | |
---|
464 | ///@brief Releases the OFDM Rx PHY master reset |
---|
465 | /// |
---|
466 | ///De-asserting RX_GLOBAL_RESET allows the Rx PHY to begin processing packets. |
---|
467 | void mimo_ofdmRx_enable(){ |
---|
468 | |
---|
469 | //Clear any stale interrupts; this should never really be required |
---|
470 | warpphy_clearRxPktStatus(); |
---|
471 | |
---|
472 | //De-asert the global reset |
---|
473 | ofdm_txrx_mimo_WriteReg_Rx_ControlBits(OFDM_BASEADDR, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(OFDM_BASEADDR) & ~RX_GLOBAL_RESET); |
---|
474 | |
---|
475 | return; |
---|
476 | } |
---|
477 | |
---|
478 | ///@brief Holds the OFDM Rx PHY in reset |
---|
479 | /// |
---|
480 | ///Asserting the RX_GLOBAL_RESET bit clears nearly all the state in the OFDM Rx. Configuration registers are not cleared. |
---|
481 | void mimo_ofdmRx_disable(){ |
---|
482 | |
---|
483 | //Assert the global reset |
---|
484 | ofdm_txrx_mimo_WriteReg_Rx_ControlBits(OFDM_BASEADDR, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(OFDM_BASEADDR) | RX_GLOBAL_RESET); |
---|
485 | |
---|
486 | //Clear any stale interrupts; this should never really be required |
---|
487 | warpphy_clearRxPktStatus(); |
---|
488 | |
---|
489 | return; |
---|
490 | } |
---|
491 | |
---|
492 | ///@brief Configures options in the Rx PHY |
---|
493 | /// |
---|
494 | ///@param someOptions 32-bit options value, composed on bitwise OR'd values from warpphy.h |
---|
495 | ///@param blockingStatusBits Configures which PHY Rx events block future receptions (good/bad header/payload) |
---|
496 | void mimo_ofdmRx_setOptions(unsigned int someOptions, unsigned int blockingStatusBits){ |
---|
497 | |
---|
498 | //Write the full controlBits register |
---|
499 | ofdm_txrx_mimo_WriteReg_Rx_ControlBits(OFDM_BASEADDR, someOptions); |
---|
500 | |
---|
501 | //The interrupt control bits are in the Interrupt_PktBuf_Ctrl register - bits[7:4] |
---|
502 | //Clear the interrupt control bits |
---|
503 | ofdm_txrx_mimo_WriteReg_TxRx_Interrupt_PktBuf_Ctrl(OFDM_BASEADDR, ofdm_txrx_mimo_ReadReg_TxRx_Interrupt_PktBuf_Ctrl(OFDM_BASEADDR) & 0xFFFFFF00); |
---|
504 | |
---|
505 | //Write just the interrupt control bits |
---|
506 | ofdm_txrx_mimo_WriteReg_TxRx_Interrupt_PktBuf_Ctrl(OFDM_BASEADDR, ofdm_txrx_mimo_ReadReg_TxRx_Interrupt_PktBuf_Ctrl(OFDM_BASEADDR) | (ALL_STATUSBITS_ENABLE & blockingStatusBits)); |
---|
507 | |
---|
508 | return; |
---|
509 | } |
---|
510 | |
---|
511 | ///@brief Returns the current value of the Rx PHY configuration register |
---|
512 | /// |
---|
513 | /// Returns the value of the OFDM Rx ControlBits register. Use the bit masks from warpphy.h to decode the indivitual bits. |
---|
514 | unsigned int mimo_ofdmRx_getOptions(){ |
---|
515 | |
---|
516 | return ofdm_txrx_mimo_ReadReg_Rx_ControlBits(OFDM_BASEADDR); |
---|
517 | } |
---|
518 | |
---|
519 | |
---|
520 | ///@brief Holds the OFDM Tx in reset |
---|
521 | /// |
---|
522 | /// Holds the OFDM Tx in reset; this prevents any state changes in the Tx PHY. Configuration registers are not affected. |
---|
523 | void mimo_ofdmTx_disable(){ |
---|
524 | |
---|
525 | //Assert the OFDM Tx master reset and pktDone reset |
---|
526 | ofdm_txrx_mimo_WriteReg_Tx_Start_Reset_Control(OFDM_BASEADDR, TX_MASTER_RESET); |
---|
527 | |
---|
528 | return; |
---|
529 | } |
---|
530 | |
---|
531 | ///@brief Releases the OFDM Tx reset |
---|
532 | /// |
---|
533 | /// Releases the OFDM Tx reset |
---|
534 | void mimo_ofdmTx_enable(){ |
---|
535 | |
---|
536 | //Assert then clear the OFDM Tx master reset and pktDone reset |
---|
537 | ofdm_txrx_mimo_WriteReg_Tx_Start_Reset_Control(OFDM_BASEADDR, TX_MASTER_RESET); |
---|
538 | ofdm_txrx_mimo_WriteReg_Tx_Start_Reset_Control(OFDM_BASEADDR, 0x0); |
---|
539 | |
---|
540 | return; |
---|
541 | } |
---|
542 | |
---|
543 | |
---|
544 | ///@brief Initiates the transmission of a packet |
---|
545 | /// |
---|
546 | ///Starts the transmission of a packet from the OFDM Tx PHY. If blocking is enabled, this function returns only |
---|
547 | ///after the transmission finishes. In this mode, the radio receiver is automatically re-enabled. If blocking is disabled, |
---|
548 | ///the receiver must be re-enabled in user code later. |
---|
549 | /// |
---|
550 | ///@param block DEPRECATED Selects whether this funciton blocks until the transmission finishes; use TXBLOCK or TXNOBLOCK |
---|
551 | inline int warpphy_pktTx(unsigned int block){ |
---|
552 | |
---|
553 | |
---|
554 | /* Should there be a check here whether the Rx PHY is receiving a packet? |
---|
555 | And what should happen if it is? It's sort of carrier sensing, but if |
---|
556 | CSMA is disabled, should the Tx pkt be discarded, or held until the Rx |
---|
557 | is no longer busy... |
---|
558 | */ |
---|
559 | |
---|
560 | //Pulse the PHY's TxEn register bit. This will propogate to the radio bridge to activate |
---|
561 | // the radio controller's Tx state machine for whatever radio is enabled (by setAntennaMode() ) |
---|
562 | mimo_ofdmTx_setStartTx(1); |
---|
563 | mimo_ofdmTx_setStartTx(0); |
---|
564 | |
---|
565 | //Sleep long enough for the PHY to start transmitting; depends on second argument to SetTxTiming |
---|
566 | usleep(6); |
---|
567 | |
---|
568 | //Return successfully |
---|
569 | return 0; |
---|
570 | } |
---|
571 | |
---|
572 | ///@brief Polls PHY transmitter and re-enables reception upon completion |
---|
573 | /// |
---|
574 | ///This function blocks until the transmitter is complete and then re-enables |
---|
575 | ///reception by enabing the radio receiver and enabling packet detection. |
---|
576 | int warpphy_waitForTx(){ |
---|
577 | |
---|
578 | //warpmac_setDebugGPIO(0xF); |
---|
579 | |
---|
580 | //Poll the PHY transmitter until it's finished transmitting |
---|
581 | while(ofdm_txrx_mimo_ReadReg_Tx_PktRunning(OFDM_BASEADDR) & OFDM_TX_BUSY) { |
---|
582 | //warpmac_incrementLEDLow(); |
---|
583 | } |
---|
584 | |
---|
585 | //Workaround for very rare PHY race condition, where a goodHeader event occurred immediately |
---|
586 | // before the transmission |
---|
587 | warpphy_clearRxPktStatus(); |
---|
588 | |
---|
589 | return 0; |
---|
590 | } |
---|
591 | |
---|
592 | |
---|
593 | ///@brief Sets the packet buffer indicies for the OFDM Tx and Rx PHY. |
---|
594 | /// |
---|
595 | ///The PLB_BRAM used a the PHY packet buffer is large enough to hold many PHY packets. |
---|
596 | ///This BRAM is divided into many sub-buffers; the PHY can be set to use any sub-buffer for Tx or Rx. |
---|
597 | /// |
---|
598 | ///@param txBufOffset 6-bit integer selecting the sub-buffer for the PHY Tx |
---|
599 | ///@param rxBufOffset 6-bit integer selecting the sub-buffer for the PHY Rx |
---|
600 | void warpphy_setBuffs(unsigned char txBufOffset, unsigned char rxBufOffset){ |
---|
601 | |
---|
602 | //TxRx_Interrupt_PktBuf_Ctrl[21:16] compose the Rx buffer offset |
---|
603 | //TxRx_Interrupt_PktBuf_Ctrl[13:8] compose the Tx buffer offset |
---|
604 | |
---|
605 | //First, zero out the current pkt buff offsets |
---|
606 | //Preserve the bottom 8 bits of the register (used for interrupt control) |
---|
607 | ofdm_txrx_mimo_WriteReg_TxRx_Interrupt_PktBuf_Ctrl(OFDM_BASEADDR, ofdm_txrx_mimo_ReadReg_TxRx_Interrupt_PktBuf_Ctrl(OFDM_BASEADDR) & 0x000000FF); |
---|
608 | |
---|
609 | //Then write the new pkt buff offsets |
---|
610 | ofdm_txrx_mimo_WriteReg_TxRx_Interrupt_PktBuf_Ctrl(OFDM_BASEADDR, |
---|
611 | ofdm_txrx_mimo_ReadReg_TxRx_Interrupt_PktBuf_Ctrl(OFDM_BASEADDR) | |
---|
612 | ( (txBufOffset & 0x3F) << 8 ) | |
---|
613 | ( (rxBufOffset & 0x3F) << 16 ) |
---|
614 | ); |
---|
615 | |
---|
616 | return; |
---|
617 | } |
---|
618 | |
---|
619 | void warpphy_AFrecordEnable(unsigned char recordEn) |
---|
620 | { |
---|
621 | if(recordEn) |
---|
622 | { |
---|
623 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() | AF_SAVEWAVEFORM, activePHYStatusBits); |
---|
624 | } |
---|
625 | else |
---|
626 | { |
---|
627 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() & ~(AF_SAVEWAVEFORM), activePHYStatusBits); |
---|
628 | } |
---|
629 | |
---|
630 | return; |
---|
631 | } |
---|
632 | |
---|
633 | ///@brief Configures the PHY for the chosen antenna modes (SISO, Alamouti, multiplexing, etc.) |
---|
634 | /// |
---|
635 | ///@param txMode Constant (defined in warphphy.h) specifying the Tx antenna mode |
---|
636 | ///@param rxMode Constant (defined in warphphy.h) specifying the Rx antenna mode |
---|
637 | int warpphy_setAntennaMode(unsigned int txMode, unsigned int rxMode) |
---|
638 | { |
---|
639 | //Reset the Tx and Rx PHYs during this reconfiguration |
---|
640 | // This will interrupt any active Tx/Rx events but won't clear any registers |
---|
641 | mimo_ofdmRx_disable(); |
---|
642 | mimo_ofdmTx_disable(); |
---|
643 | |
---|
644 | //Tx configuration |
---|
645 | if(txMode != ANTMODE_UNCHANGED) |
---|
646 | { |
---|
647 | //Update the gloabl variable (used throughout to calculate "magic" numbers for the PHY) |
---|
648 | warpphy_txAntMode = txMode; |
---|
649 | |
---|
650 | //Take software control and disable both radio's Tx paths |
---|
651 | // The correct radios will be re-enabled below |
---|
652 | WarpRadio_v1_TxEnSoftControlEnable(BOTH_RADIOS); |
---|
653 | WarpRadio_v1_TxRxDisable(BOTH_RADIOS); |
---|
654 | |
---|
655 | //Enable hardware Tx control of either or both radios |
---|
656 | switch(txMode & ANTMODE_MASK_ANTSEL) |
---|
657 | { |
---|
658 | case ANTMODE_ANTSEL_RADA: |
---|
659 | activeRadios_Tx = FIRST_RADIO; |
---|
660 | WarpRadio_v1_TxEnSoftControlDisable(FIRST_RADIO); |
---|
661 | break; |
---|
662 | |
---|
663 | case ANTMODE_ANTSEL_RADB: |
---|
664 | activeRadios_Tx = SECOND_RADIO; |
---|
665 | WarpRadio_v1_TxEnSoftControlDisable(SECOND_RADIO); |
---|
666 | break; |
---|
667 | |
---|
668 | case ANTMODE_ANTSEL_BOTHRADS: |
---|
669 | activeRadios_Tx = BOTH_RADIOS; |
---|
670 | WarpRadio_v1_TxEnSoftControlDisable(BOTH_RADIOS); |
---|
671 | break; |
---|
672 | |
---|
673 | default: |
---|
674 | xil_printf("Invalid Tx antenna mode!\r\n"); |
---|
675 | return -1; |
---|
676 | break; |
---|
677 | } |
---|
678 | |
---|
679 | //Configure the PHY's Tx mode |
---|
680 | switch(txMode & ANTMODE_MASK_PHYMODE) |
---|
681 | { |
---|
682 | case PHYMODE_SISO: |
---|
683 | //Set SISO mode, disable MIMO modes in the Tx PHY registers |
---|
684 | mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & ~(TX_ALAMOUTI_MODE) ); |
---|
685 | mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | TX_SISO_MODE); |
---|
686 | break; |
---|
687 | |
---|
688 | case PHYMODE_2X2MULT: |
---|
689 | //Disable SISO/Alamouti modes in the Tx PHY registers |
---|
690 | mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & ~(TX_SISO_MODE | TX_ALAMOUTI_MODE) ); |
---|
691 | break; |
---|
692 | |
---|
693 | case PHYMODE_ALAMOUTI: |
---|
694 | //Set Alamouti mode, disable SISO mode in the Tx PHY registers |
---|
695 | mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & ~(TX_SISO_MODE) ); |
---|
696 | mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | TX_ALAMOUTI_MODE); |
---|
697 | break; |
---|
698 | |
---|
699 | default: |
---|
700 | xil_printf("Invalid Tx PHY mode!\r\n"); |
---|
701 | return -1; |
---|
702 | break; |
---|
703 | } |
---|
704 | |
---|
705 | //Configure the PHY's Tx antenna configuration |
---|
706 | switch(txMode & ANTMODE_MASK_PHYANTCFG) |
---|
707 | { |
---|
708 | case PHYANTCFG_TX_NORMAL: |
---|
709 | mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & ~(TX_SWAP_ANTENNAS) ); |
---|
710 | break; |
---|
711 | |
---|
712 | case PHYANTCFG_TX_SWAPPED: |
---|
713 | mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | TX_SWAP_ANTENNAS); |
---|
714 | break; |
---|
715 | |
---|
716 | default: |
---|
717 | xil_printf("Invalid Tx PHYANT mode!\r\n"); |
---|
718 | return -1; |
---|
719 | break; |
---|
720 | } |
---|
721 | } |
---|
722 | |
---|
723 | if(rxMode != ANTMODE_UNCHANGED) |
---|
724 | { |
---|
725 | //Update the gloabl variable (used throughout to calculate "magic" numbers for the PHY) |
---|
726 | warpphy_rxAntMode = rxMode; |
---|
727 | |
---|
728 | //Take software control and disable both radio's Rx paths |
---|
729 | // The correct radios will be re-enabled below |
---|
730 | WarpRadio_v1_RxEnSoftControlEnable(BOTH_RADIOS); |
---|
731 | WarpRadio_v1_TxRxDisable(BOTH_RADIOS); |
---|
732 | |
---|
733 | //Enable hardware Rx control of either or both radios |
---|
734 | switch(rxMode & ANTMODE_MASK_ANTSEL) |
---|
735 | { |
---|
736 | case ANTMODE_ANTSEL_RADA: |
---|
737 | activeRadios_Rx = FIRST_RADIO; |
---|
738 | WarpRadio_v1_RxEnSoftControlDisable(FIRST_RADIO); |
---|
739 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setMask(PKTDET_MASK_ANTA); |
---|
740 | break; |
---|
741 | |
---|
742 | case ANTMODE_ANTSEL_RADB: |
---|
743 | activeRadios_Rx = SECOND_RADIO; |
---|
744 | WarpRadio_v1_RxEnSoftControlDisable(SECOND_RADIO); |
---|
745 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setMask(PKTDET_MASK_ANTB); |
---|
746 | break; |
---|
747 | |
---|
748 | case ANTMODE_ANTSEL_BOTHRADS: |
---|
749 | activeRadios_Rx = BOTH_RADIOS; |
---|
750 | WarpRadio_v1_RxEnSoftControlDisable(BOTH_RADIOS); |
---|
751 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setMask(PKTDET_MASK_ANTA | PKTDET_MASK_ANTB); |
---|
752 | break; |
---|
753 | |
---|
754 | default: |
---|
755 | xil_printf("Invalid Rx antenna mode!\r\n"); |
---|
756 | return -1; |
---|
757 | break; |
---|
758 | } |
---|
759 | |
---|
760 | |
---|
761 | //Configure the PHY's Rx mode |
---|
762 | switch(rxMode & ANTMODE_MASK_PHYMODE) |
---|
763 | { |
---|
764 | case PHYMODE_SISO: |
---|
765 | //Set SISO mode, disable MIMO modes in the Rx PHY registers |
---|
766 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() & ~(RX_ALAMOUTI_MODE), activePHYStatusBits); |
---|
767 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() | RX_SISO_MODE, activePHYStatusBits); |
---|
768 | mimo_ofdmRx_setRxScaling(0x10001000); |
---|
769 | break; |
---|
770 | |
---|
771 | case PHYMODE_2X2MULT: |
---|
772 | //Disable SISO/Alamouti modes in the Rx PHY registers |
---|
773 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() & ~(RX_ALAMOUTI_MODE | RX_SISO_MODE), activePHYStatusBits); |
---|
774 | mimo_ofdmRx_setRxScaling(0x08000800); |
---|
775 | break; |
---|
776 | |
---|
777 | case PHYMODE_ALAMOUTI: |
---|
778 | //Set Alamouti mode, disable SISO mode in the Rx PHY registers |
---|
779 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() & ~(RX_SISO_MODE), activePHYStatusBits); |
---|
780 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() | RX_ALAMOUTI_MODE, activePHYStatusBits); |
---|
781 | mimo_ofdmRx_setRxScaling(0x08000800); |
---|
782 | break; |
---|
783 | |
---|
784 | default: |
---|
785 | xil_printf("Invalid Rx PHY mode!\r\n"); |
---|
786 | return -1; |
---|
787 | break; |
---|
788 | } |
---|
789 | |
---|
790 | //Configure the PHY's Rx antenna configuration |
---|
791 | switch(rxMode & ANTMODE_MASK_PHYANTCFG) |
---|
792 | { |
---|
793 | case PHYANTCFG_RX_NORMAL: |
---|
794 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() & ~(SISO_ON_ANTB | SWITCHING_DIV_EN), activePHYStatusBits); |
---|
795 | break; |
---|
796 | |
---|
797 | case PHYANTCFG_RX_SWAPPED: |
---|
798 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() & ~(SWITCHING_DIV_EN), activePHYStatusBits); |
---|
799 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() | SISO_ON_ANTB, activePHYStatusBits); |
---|
800 | break; |
---|
801 | |
---|
802 | case PHYANTCFG_RX_SELDIV: |
---|
803 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() & ~(SISO_ON_ANTB), activePHYStatusBits); |
---|
804 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() | SWITCHING_DIV_EN, activePHYStatusBits); |
---|
805 | break; |
---|
806 | |
---|
807 | default: |
---|
808 | xil_printf("Invalid Rx PHYANT mode!\r\n"); |
---|
809 | return -1; |
---|
810 | break; |
---|
811 | |
---|
812 | } |
---|
813 | } |
---|
814 | |
---|
815 | //Finally, re-enbale the PHY Tx/Rx subsystems |
---|
816 | mimo_ofdmRx_enable(); |
---|
817 | mimo_ofdmTx_enable(); |
---|
818 | |
---|
819 | //Pulse the PHY's RxEn register to re-enable receive paths on the active radios |
---|
820 | // This must occur after calling ofdmRx_enable, as this register's output is ignored while the Rx PHY is in reset |
---|
821 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() | PHY_RADIO_RXEN, activePHYStatusBits); |
---|
822 | mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() & ~(PHY_RADIO_RXEN), activePHYStatusBits); |
---|
823 | |
---|
824 | return 0; |
---|
825 | } |
---|
826 | |
---|
827 | ///@brief Fast and dangerous way of switching TX PHY mode... note... this function cannot change physical radios |
---|
828 | /// |
---|
829 | ///@param txMode Constant (defined in warphphy.h) specifying the Tx antenna mode |
---|
830 | int warpphy_setTxAntennaSwap(unsigned int txMode) |
---|
831 | { |
---|
832 | //Tx configuration |
---|
833 | if(txMode != ANTMODE_UNCHANGED) |
---|
834 | { |
---|
835 | //Update the gloabl variable (used throughout to calculate "magic" numbers for the PHY) |
---|
836 | warpphy_txAntMode = txMode; |
---|
837 | |
---|
838 | //Configure the PHY's Tx antenna configuration |
---|
839 | switch(txMode & ANTMODE_MASK_PHYANTCFG) |
---|
840 | { |
---|
841 | case PHYANTCFG_TX_NORMAL: |
---|
842 | mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & ~(TX_SWAP_ANTENNAS) ); |
---|
843 | break; |
---|
844 | |
---|
845 | case PHYANTCFG_TX_SWAPPED: |
---|
846 | mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | TX_SWAP_ANTENNAS); |
---|
847 | break; |
---|
848 | |
---|
849 | default: |
---|
850 | xil_printf("Invalid Tx PHYANT mode!\r\n"); |
---|
851 | return -1; |
---|
852 | break; |
---|
853 | } |
---|
854 | } |
---|
855 | |
---|
856 | return 0; |
---|
857 | } |
---|
858 | |
---|
859 | inline void warpphy_clearAutoResponseFlag(unsigned char flagID){ |
---|
860 | |
---|
861 | switch(flagID) |
---|
862 | { |
---|
863 | case AUTORESP_FLAGID_A: |
---|
864 | ofdm_txrx_mimo_WriteReg_Rx_ControlBits(OFDM_BASEADDR, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(OFDM_BASEADDR) | (AUTORESP_FLAGA_RST)); |
---|
865 | ofdm_txrx_mimo_WriteReg_Rx_ControlBits(OFDM_BASEADDR, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(OFDM_BASEADDR) & ~(AUTORESP_FLAGA_RST)); |
---|
866 | break; |
---|
867 | case AUTORESP_FLAGID_B: |
---|
868 | ofdm_txrx_mimo_WriteReg_Rx_ControlBits(OFDM_BASEADDR, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(OFDM_BASEADDR) | (AUTORESP_FLAGB_RST)); |
---|
869 | ofdm_txrx_mimo_WriteReg_Rx_ControlBits(OFDM_BASEADDR, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(OFDM_BASEADDR) & ~(AUTORESP_FLAGB_RST)); |
---|
870 | break; |
---|
871 | } |
---|
872 | |
---|
873 | return; |
---|
874 | } |
---|
875 | |
---|
876 | ///@brief Sets the number of training symbol periods used per packet |
---|
877 | /// |
---|
878 | ///Configures the number of training symbols which are transmitted with each packet. The Tx and Rx nodes must be |
---|
879 | ///configured for the same number. In SISO mode, the single channel is trained c times. In MIMO mode, each channel |
---|
880 | ///is trained c/2 times |
---|
881 | /// |
---|
882 | ///@param numTraining number of training periods; must be even |
---|
883 | void warpphy_setNumTrainingSyms(unsigned int numTraining){ |
---|
884 | //Update the global variable; used each time a packet is transmitted |
---|
885 | numTrainingSyms = numTraining; |
---|
886 | |
---|
887 | //Configure the PHY |
---|
888 | warpphy_setTxNumSyms(numBaseRate, numTrainingSyms); |
---|
889 | warpphy_setRxNumSyms(numBaseRate, numTrainingSyms); |
---|
890 | } |
---|
891 | |
---|
892 | void warpphy_setNumBaseRateSyms(unsigned int numSyms){ |
---|
893 | //Update the global variable; used each time a packet is transmitted |
---|
894 | numBaseRate = numSyms; |
---|
895 | |
---|
896 | //Configure the PHY |
---|
897 | warpphy_setTxNumSyms(numBaseRate, numTrainingSyms); |
---|
898 | warpphy_setRxNumSyms(numBaseRate, numTrainingSyms); |
---|
899 | } |
---|
900 | |
---|
901 | ///@brief Configure the flexible modulation/demodulation in the OFDM PHY |
---|
902 | /// |
---|
903 | ///The OFDM PHY supports flexible modulation, allowing any combination of schemes per subcarrier |
---|
904 | ///Currently this code supports simple dynamic modulation, with 48 of 64 subcarriers assigned to carry data, 4 for pilots and 12 empty. |
---|
905 | ///The modulation scheme in the 48 data subcarriers is set by this funciton. |
---|
906 | ///NOTE: When FEC is enabled the modulation rate of all data bearing subcarriers must be the same and one of BPSK/QPSK/16-QAM |
---|
907 | /// |
---|
908 | ///@param baseRate Modulation scheme for base rate symbols |
---|
909 | ///@param TxAntAFullRate Modulation scheme for Tx full rate symbols on antenna A |
---|
910 | ///@param TxAntBFullRate Modulation scheme for Tx full rate symbols on antenna B |
---|
911 | ///@param RxAntAFullRate Modulation scheme for Rx full rate symbols on antenna A |
---|
912 | ///@param RxAntBFullRate Modulation scheme for Rx full rate symbols on antenna B |
---|
913 | void warpphy_set_modulation(unsigned char baseRate, unsigned char TxAntAFullRate, unsigned char TxAntBFullRate, unsigned char RxAntAFullRate, unsigned char RxAntBFullRate) |
---|
914 | { |
---|
915 | unsigned int modIndex; |
---|
916 | |
---|
917 | //Define the standard subcarrier mapping - 48 used for data (0xF here), 4 pilots & 12 unused (0x0 here) |
---|
918 | // The vector contains 192 elements: |
---|
919 | // 0:63 - Antenna A full rate masks for subcarriers [0,1,2,...31,-31,-30,...-1] |
---|
920 | // 64:127 - Antenna B full rate masks for subcarriers [0,1,2,...31,-31,-30,...-1] |
---|
921 | // 128:191 - Base rate masks for subcarriers [0,1,2,...31,-31,-30,...-1] |
---|
922 | //The default masks are 3 copies of the same 64-length vector; yes, it's inefficient, but this scheme maintains flexibility in changing the mapping per antenna |
---|
923 | unsigned char modMasks[192] = { |
---|
924 | 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, |
---|
925 | 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, |
---|
926 | 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0x0, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF |
---|
927 | }; |
---|
928 | |
---|
929 | //The PHY's shared memories for modulation masks have 192 4-bit entries; each entry's address is 4-byte aligned (hence the *sizeof(int) below ) |
---|
930 | if(TxAntAFullRate != MOD_UNCHANGED) |
---|
931 | { |
---|
932 | //Configure Tx antenna A full rate |
---|
933 | for(modIndex=0; modIndex<64; modIndex++) |
---|
934 | { |
---|
935 | XIo_Out32(XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_TXMODULATION+(modIndex*sizeof(int)), modMasks[modIndex] & TxAntAFullRate); |
---|
936 | } |
---|
937 | } |
---|
938 | |
---|
939 | if(TxAntBFullRate != MOD_UNCHANGED) |
---|
940 | { |
---|
941 | //Configure Tx antenna B full rate |
---|
942 | for(modIndex=64; modIndex<128; modIndex++) |
---|
943 | { |
---|
944 | XIo_Out32(XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_TXMODULATION+(modIndex*sizeof(int)), modMasks[modIndex] & TxAntBFullRate); |
---|
945 | } |
---|
946 | } |
---|
947 | |
---|
948 | if(RxAntAFullRate != MOD_UNCHANGED) |
---|
949 | { |
---|
950 | //Configure Rx antenna A full rate |
---|
951 | for(modIndex=0; modIndex<64; modIndex++) |
---|
952 | { |
---|
953 | XIo_Out32(XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_RXMODULATION+(modIndex*sizeof(int)), modMasks[modIndex] & RxAntAFullRate); |
---|
954 | } |
---|
955 | } |
---|
956 | |
---|
957 | if(RxAntBFullRate != MOD_UNCHANGED) |
---|
958 | { |
---|
959 | //Configure Rx antenna B full rate |
---|
960 | for(modIndex=64; modIndex<128; modIndex++) |
---|
961 | { |
---|
962 | XIo_Out32(XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_RXMODULATION+(modIndex*sizeof(int)), modMasks[modIndex] & RxAntBFullRate); |
---|
963 | } |
---|
964 | } |
---|
965 | |
---|
966 | //Update the global baseRate modulation variable |
---|
967 | if(baseRate != MOD_UNCHANGED) |
---|
968 | { |
---|
969 | baseRateMod = baseRate; |
---|
970 | |
---|
971 | //Configure the Tx and Rx base rate |
---|
972 | for(modIndex=128; modIndex<192; modIndex++) |
---|
973 | { |
---|
974 | XIo_Out32(XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_TXMODULATION+(modIndex*sizeof(int)), modMasks[modIndex] & baseRate); |
---|
975 | XIo_Out32(XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_RXMODULATION+(modIndex*sizeof(int)), modMasks[modIndex] & baseRate); |
---|
976 | } |
---|
977 | } |
---|
978 | |
---|
979 | return; |
---|
980 | } |
---|
981 | |
---|
982 | ///@brief Set the center frequency of the radio transceivers |
---|
983 | ///@param band Selects 2.4GHz or 5GHz bands (using GHZ_2 or GHZ_5) |
---|
984 | ///@param chan Selects the channel number in the chosen band |
---|
985 | ///@return Returns -1 if an invalid band or channel was specified; otherwise returns the new center frequency in MHz |
---|
986 | int warpphy_setChannel(unsigned char band, unsigned int chan){ |
---|
987 | int newFreq = -1; |
---|
988 | |
---|
989 | if (band == GHZ_2){ |
---|
990 | newFreq = WarpRadio_v1_SetCenterFreq2GHz(chan, FIRST_RADIO | SECOND_RADIO); |
---|
991 | } |
---|
992 | if (band == GHZ_5){ |
---|
993 | newFreq = WarpRadio_v1_SetCenterFreq5GHz(chan, FIRST_RADIO | SECOND_RADIO); |
---|
994 | } |
---|
995 | |
---|
996 | return newFreq; |
---|
997 | } |
---|
998 | |
---|
999 | ///@brief Set the center frequency of the radio transceivers independently |
---|
1000 | ///@param antA_band Selects 2.4GHz or 5GHz bands (using GHZ_2 or GHZ_5) for antenna A |
---|
1001 | ///@param antB_band Selects 2.4GHz or 5GHz bands (using GHZ_2 or GHZ_5) for antenna B |
---|
1002 | ///@param antA_chan Selects the channel number in the chosen band for antenna A |
---|
1003 | ///@param antB_chan Selects the channel number in the chosen band for antenna B |
---|
1004 | ///@return Returns -1 if an invalid band or channel was specified; otherwise returns the new center frequency for antenna A in MHz |
---|
1005 | int warpphy_setSeparateChannels(unsigned char antA_band, unsigned int antA_chan, unsigned char antB_band, unsigned int antB_chan){ |
---|
1006 | |
---|
1007 | int newFreq_A = -1; |
---|
1008 | int newFreq_B = -1; |
---|
1009 | |
---|
1010 | if (antA_band == GHZ_2) |
---|
1011 | newFreq_A = WarpRadio_v1_SetCenterFreq2GHz(antA_chan, FIRST_RADIO); |
---|
1012 | if (antB_band == GHZ_2) |
---|
1013 | newFreq_B = WarpRadio_v1_SetCenterFreq2GHz(antB_chan, SECOND_RADIO); |
---|
1014 | if (antA_band == GHZ_5) |
---|
1015 | newFreq_A = WarpRadio_v1_SetCenterFreq5GHz(antA_chan, FIRST_RADIO); |
---|
1016 | if (antB_band == GHZ_5) |
---|
1017 | newFreq_B = WarpRadio_v1_SetCenterFreq5GHz(antB_chan, SECOND_RADIO); |
---|
1018 | if(newFreq_A == -1 || newFreq_B == -1) |
---|
1019 | return -1; |
---|
1020 | else |
---|
1021 | return newFreq_A; |
---|
1022 | } |
---|
1023 | |
---|
1024 | ///@brief Applies TX DC offset calibration to the specified radios; the calibration values are stored in the radio's EEPROM |
---|
1025 | ///@param radioSelection OR'd combinaton of RADIOx_ADDR values, specifying which radios to update |
---|
1026 | ///@return Returns -1 if an EEPROM error occurs; returns 0 if successful |
---|
1027 | int warpphy_applyTxDCOCalibration(unsigned int radioSelection) |
---|
1028 | { |
---|
1029 | int eepromStatus = 0; |
---|
1030 | short calReadback = 0; |
---|
1031 | signed short best_I, best_Q; |
---|
1032 | unsigned char radioNum; |
---|
1033 | Xuint8 memory[8], version, revision, valid; |
---|
1034 | Xuint16 serial; |
---|
1035 | |
---|
1036 | //Radio selection will be 0x11111111, 0x22222222, 0x44444444 or 0x88888888 |
---|
1037 | // corresponding to radios in slots 1, 2, 3 or 4 |
---|
1038 | // We need the slot number to initialize the EEPROM |
---|
1039 | radioNum = (radioSelection & 0xF) == 1 ? 1 : ( (radioSelection & 0xF) == 2 ? 2 : ( (radioSelection & 0xF) == 4 ? 3 : 4 ) ); |
---|
1040 | // xil_printf("Applying TxDCO correction for radio %d\r\n", radioNum); |
---|
1041 | |
---|
1042 | //Mimic the radio test code, in hopes of a more stable EEPROM read... |
---|
1043 | //Choose the EEPROM on the selected radio board; second arg is [0,1,2,3,4] for [FPGA, radio1, radio2, radio3, radio4] |
---|
1044 | eepromStatus = WarpEEPROM_EEPROMSelect((unsigned int *)XPAR_EEPROM_CONTROLLER_MEM0_BASEADDR, 0); |
---|
1045 | if(eepromStatus != 0) |
---|
1046 | { |
---|
1047 | xil_printf("EEPROM Select Failed!\r\n"); |
---|
1048 | return -1; |
---|
1049 | } |
---|
1050 | |
---|
1051 | //Initialize the EEPROM controller |
---|
1052 | eepromStatus = WarpEEPROM_Initialize((unsigned int *)XPAR_EEPROM_CONTROLLER_MEM0_BASEADDR); |
---|
1053 | if(eepromStatus != 0) |
---|
1054 | { |
---|
1055 | xil_printf("EEPROM Init Returned %x\r\n", eepromStatus); |
---|
1056 | xil_printf("EEPROM Init Failed!\r\n"); |
---|
1057 | return -1; |
---|
1058 | } |
---|
1059 | |
---|
1060 | //Select the EEPROM on the current radio board |
---|
1061 | eepromStatus = WarpEEPROM_EEPROMSelect((unsigned int*)XPAR_EEPROM_CONTROLLER_MEM0_BASEADDR, radioNum); |
---|
1062 | |
---|
1063 | if(eepromStatus != 0) |
---|
1064 | { |
---|
1065 | xil_printf("TxDCO: EEPROM error\r\n"); |
---|
1066 | return -1; |
---|
1067 | } |
---|
1068 | |
---|
1069 | //Read the first page from the EERPOM |
---|
1070 | WarpEEPROM_ReadMem((unsigned int*)XPAR_EEPROM_CONTROLLER_MEM0_BASEADDR, 0, 0, memory); |
---|
1071 | version = (memory[0] & 0xE0) >> 5; |
---|
1072 | revision = (memory[1] & 0xE0) >> 5; |
---|
1073 | valid = memory[1] & 0x1F; |
---|
1074 | |
---|
1075 | // xil_printf("\r\n\r\nEEPROM Values for Radio Board in Slot %d\r\n", radioNum); |
---|
1076 | |
---|
1077 | // xil_printf(" WARP Radio Board Version %d.%d\r\n", version, revision); |
---|
1078 | |
---|
1079 | serial = WarpEEPROM_ReadWARPSerial((unsigned int*)XPAR_EEPROM_CONTROLLER_MEM0_BASEADDR); |
---|
1080 | |
---|
1081 | // xil_printf(" Serial Number (WARP): WR-a-%05d\r\n", serial); |
---|
1082 | |
---|
1083 | WarpEEPROM_ReadDSSerial((unsigned int*)XPAR_EEPROM_CONTROLLER_MEM0_BASEADDR, memory); |
---|
1084 | // print(" EEPROM Hard-wired Serial Number: "); |
---|
1085 | // for(i=1;i<7;i++) |
---|
1086 | // xil_printf(" %x",memory[7-i]); |
---|
1087 | // xil_printf("\r\n\r\n"); |
---|
1088 | //Read the Tx DCO values |
---|
1089 | calReadback = WarpEEPROM_ReadRadioCal((unsigned int*)XPAR_EEPROM_CONTROLLER_MEM0_BASEADDR, 2, 1); |
---|
1090 | |
---|
1091 | //Scale the stored values |
---|
1092 | best_I = (signed short)(((signed char)(calReadback & 0xFF))<<1); |
---|
1093 | best_Q = (signed short)(((signed char)((calReadback>>8) & 0xFF))<<1); |
---|
1094 | |
---|
1095 | xil_printf("\t\tTxDCO values for radio %d - I: %d\tQ: %d\r\n", radioNum, best_I, best_Q); |
---|
1096 | |
---|
1097 | //Finally, write the Tx DCO values to the DAC |
---|
1098 | WarpRadio_v1_DACOffsetAdj(ICHAN, best_I, radioSelection); |
---|
1099 | WarpRadio_v1_DACOffsetAdj(QCHAN, best_Q, radioSelection); |
---|
1100 | |
---|
1101 | return 0; |
---|
1102 | } |
---|
1103 | |
---|
1104 | |
---|
1105 | /******* AGC core control functions ********/ |
---|
1106 | |
---|
1107 | unsigned int warpphy_returnGainsDB(){ |
---|
1108 | /* int rfGain; |
---|
1109 | switch(warpphy_returnAGCgainRF(antenna)){ |
---|
1110 | case 0: |
---|
1111 | rfGain=1; |
---|
1112 | break; |
---|
1113 | case 1: |
---|
1114 | rfGain=16; |
---|
1115 | break; |
---|
1116 | case 2: |
---|
1117 | rfGain=31.5; |
---|
1118 | break; |
---|
1119 | } |
---|
1120 | xil_printf("BBGAIN %d\r\n",(warpphy_returnAGCgainBB(antenna)<<1)); |
---|
1121 | return ((warpphy_returnAGCgainBB(antenna)<<1) + rfGain); |
---|
1122 | */ |
---|
1123 | |
---|
1124 | unsigned int rfGain,bbGain,gainDB,rfGainDB,bbGainDB; |
---|
1125 | unsigned int agcGains; |
---|
1126 | |
---|
1127 | |
---|
1128 | agcGains = ofdm_AGC_GetGains(); |
---|
1129 | rfGain = agcGains&0x3; |
---|
1130 | bbGain = (agcGains>>2)&0x1F; |
---|
1131 | |
---|
1132 | switch(rfGain){ |
---|
1133 | case 0: |
---|
1134 | rfGainDB=1; |
---|
1135 | break; |
---|
1136 | case 1: |
---|
1137 | rfGainDB=1; |
---|
1138 | break; |
---|
1139 | case 2: |
---|
1140 | rfGainDB=16; |
---|
1141 | break; |
---|
1142 | case 3: |
---|
1143 | rfGainDB=32; //really 31.5... |
---|
1144 | break; |
---|
1145 | } |
---|
1146 | |
---|
1147 | bbGainDB=bbGain<<1; |
---|
1148 | gainDB = bbGainDB + rfGainDB; |
---|
1149 | return gainDB; |
---|
1150 | |
---|
1151 | |
---|
1152 | |
---|
1153 | |
---|
1154 | } |
---|
1155 | |
---|
1156 | |
---|
1157 | |
---|
1158 | |
---|
1159 | inline void ofdm_AGC_SetDCO(unsigned int AGCstate){ |
---|
1160 | |
---|
1161 | // register bits: |
---|
1162 | // [1:0]- DCO mode |
---|
1163 | // 0x0=bypass DCO correction entirely |
---|
1164 | // 0x1=bypass IIR filter, allow subtraction |
---|
1165 | // 0x2=enable IIR filter, allow subtraction |
---|
1166 | // [2]- enable subtraction (only has effect if [1:0] != 0) |
---|
1167 | // Valid values: |
---|
1168 | // [1 1 0]=0x6: Enable filter, use subtraction |
---|
1169 | OFDM_AGC_MIMO_WriteReg_Bits(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, (AGCstate & 0x7)); |
---|
1170 | |
---|
1171 | return; |
---|
1172 | } |
---|
1173 | |
---|
1174 | void ofdm_AGC_Reset(){ |
---|
1175 | |
---|
1176 | // Cycle the agc's software reset port |
---|
1177 | |
---|
1178 | OFDM_AGC_MIMO_WriteReg_SRESET_IN(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 1); |
---|
1179 | usleep(10); |
---|
1180 | OFDM_AGC_MIMO_WriteReg_SRESET_IN(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0); |
---|
1181 | usleep(100); |
---|
1182 | |
---|
1183 | return; |
---|
1184 | } |
---|
1185 | |
---|
1186 | |
---|
1187 | void ofdm_AGC_MasterReset(){ |
---|
1188 | |
---|
1189 | // Cycle the master reset register in the AGC and enable it |
---|
1190 | |
---|
1191 | OFDM_AGC_MIMO_WriteReg_AGC_EN(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0); |
---|
1192 | usleep(10); |
---|
1193 | OFDM_AGC_MIMO_WriteReg_MRESET_IN(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0); |
---|
1194 | usleep(10); |
---|
1195 | OFDM_AGC_MIMO_WriteReg_MRESET_IN(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 1); |
---|
1196 | usleep(10); |
---|
1197 | OFDM_AGC_MIMO_WriteReg_MRESET_IN(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0); |
---|
1198 | usleep(10); |
---|
1199 | OFDM_AGC_MIMO_WriteReg_AGC_EN(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 1); |
---|
1200 | |
---|
1201 | return; |
---|
1202 | } |
---|
1203 | |
---|
1204 | void ofdm_AGC_Initialize(int noise_estimate){ |
---|
1205 | |
---|
1206 | int g_bbset = 0; |
---|
1207 | |
---|
1208 | // First set all standard parameters |
---|
1209 | |
---|
1210 | // Turn off both resets and the master enable |
---|
1211 | OFDM_AGC_MIMO_WriteReg_AGC_EN(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0); |
---|
1212 | OFDM_AGC_MIMO_WriteReg_SRESET_IN(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0); |
---|
1213 | OFDM_AGC_MIMO_WriteReg_MRESET_IN(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0); |
---|
1214 | |
---|
1215 | // An adjustment parameter |
---|
1216 | OFDM_AGC_MIMO_WriteReg_ADJ(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 8); |
---|
1217 | |
---|
1218 | // Timing for the DC-offset correction |
---|
1219 | // OFDM_AGC_MIMO_WriteReg_DCO_Timing(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0x46403003); //as used through v21 |
---|
1220 | OFDM_AGC_MIMO_WriteReg_DCO_Timing(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0x463C2C03); // |
---|
1221 | |
---|
1222 | // Initial baseband gain setting |
---|
1223 | OFDM_AGC_MIMO_WriteReg_GBB_init(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 52); |
---|
1224 | |
---|
1225 | // RF gain AGCstate thresholds |
---|
1226 | OFDM_AGC_MIMO_WriteReg_Thresholds(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, |
---|
1227 | ((AGC_THRESH_1&0xFF)<<16) + |
---|
1228 | ((AGC_THRESH_2&0xFF)<<8) + |
---|
1229 | (AGC_THRESH_3&0xFF) |
---|
1230 | ); |
---|
1231 | |
---|
1232 | // Overall AGC timing |
---|
1233 | // OFDM_AGC_MIMO_WriteReg_Timing(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0x9A962A28);//0x826E3C0A; |
---|
1234 | // OFDM_AGC_MIMO_WriteReg_Timing(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0xAA962A28);//added time between GBB change and AGC_DONE (pom 2010-06-19) |
---|
1235 | // OFDM_AGC_MIMO_WriteReg_Timing(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0xEAC65A58); |
---|
1236 | OFDM_AGC_MIMO_WriteReg_Timing(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0xFAC62A28);//delayed I/Q sensitive steps by 12 samples for new Rx filter latency |
---|
1237 | |
---|
1238 | // vIQ and RSSI average lengths |
---|
1239 | OFDM_AGC_MIMO_WriteReg_AVG_LEN(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0x10F); //103 |
---|
1240 | |
---|
1241 | // Disable DCO, disable DCO subtraction |
---|
1242 | OFDM_AGC_MIMO_WriteReg_Bits(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, 0x0); |
---|
1243 | |
---|
1244 | // Compute and set the initial g_BB gain value from the noise estimate |
---|
1245 | // The initial g_bb sets noise to -19 db, assuming 32 db RF gain |
---|
1246 | |
---|
1247 | g_bbset = -19 - 32 - noise_estimate; |
---|
1248 | OFDM_AGC_MIMO_WriteReg_GBB_init(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, g_bbset); |
---|
1249 | |
---|
1250 | // Perform a master reset |
---|
1251 | ofdm_AGC_MasterReset(); |
---|
1252 | |
---|
1253 | // Agc is now reset and enabled, ready to go! |
---|
1254 | return; |
---|
1255 | } |
---|
1256 | |
---|
1257 | |
---|
1258 | void ofdm_AGC_setNoiseEstimate(int noise_estimate){ |
---|
1259 | int g_bbset; |
---|
1260 | |
---|
1261 | g_bbset = -19 - 32 - noise_estimate; |
---|
1262 | |
---|
1263 | OFDM_AGC_MIMO_WriteReg_GBB_init(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, g_bbset); |
---|
1264 | |
---|
1265 | return; |
---|
1266 | } |
---|
1267 | |
---|
1268 | unsigned int ofdm_AGC_GetGains(void){ |
---|
1269 | |
---|
1270 | unsigned int gBB_A, gRF_A, gBB_B, gRF_B, gains; |
---|
1271 | |
---|
1272 | // Get the gains from the registers |
---|
1273 | gBB_A = OFDM_AGC_MIMO_ReadReg_GBB_A(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR); |
---|
1274 | gRF_A = OFDM_AGC_MIMO_ReadReg_GRF_A(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR); |
---|
1275 | |
---|
1276 | gBB_B = OFDM_AGC_MIMO_ReadReg_GBB_B(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR); |
---|
1277 | gRF_B = OFDM_AGC_MIMO_ReadReg_GRF_B(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR); |
---|
1278 | |
---|
1279 | // First concatenate the two radios together, into the gRF register |
---|
1280 | // 2 lowest bits are RF, 5 higher bits are BB, last bit is unused |
---|
1281 | // Multiply by 2^2, shift gBB right by 2 bits |
---|
1282 | |
---|
1283 | gRF_A = gRF_A + (gBB_A * 4); |
---|
1284 | gRF_B = gRF_B + (gBB_B * 4); |
---|
1285 | |
---|
1286 | // Multiply by 2^8 shift gRF right by 8 bits |
---|
1287 | gains = gRF_A + (gRF_B * 256); |
---|
1288 | |
---|
1289 | // Returns hi[0 gBB_B g_RF_B | 0 g_BB_A g_RF_A]lo |
---|
1290 | return gains; |
---|
1291 | } |
---|
1292 | |
---|
1293 | void ofdm_AGC_SetTarget(unsigned int target){ |
---|
1294 | OFDM_AGC_MIMO_WriteReg_T_dB(XPAR_OFDM_AGC_MIMO_OPBW_0_BASEADDR, target); |
---|
1295 | return; |
---|
1296 | } |
---|
1297 | /******* END AGC core control functions ********/ |
---|
1298 | |
---|
1299 | |
---|
1300 | |
---|
1301 | /******* WARP Timer core control functions *******/ |
---|
1302 | void warp_timer_start(unsigned char timer) { |
---|
1303 | warp_timer_WriteReg_control(warp_timer_ReadReg_control() | (TIMER_MASK_CALC(timer) & TIMER_CONTROL_START_MASK)); |
---|
1304 | warp_timer_WriteReg_control(warp_timer_ReadReg_control() & ~(TIMER_MASK_CALC(timer) & TIMER_CONTROL_START_MASK)); |
---|
1305 | } |
---|
1306 | |
---|
1307 | void warp_timer_pause(unsigned char timer) { |
---|
1308 | warp_timer_WriteReg_control(warp_timer_ReadReg_control() | (TIMER_MASK_CALC(timer) & TIMER_CONTROL_PAUSE_MASK)); |
---|
1309 | } |
---|
1310 | |
---|
1311 | void warp_timer_resume(unsigned char timer) { |
---|
1312 | warp_timer_WriteReg_control(warp_timer_ReadReg_control() & ~(TIMER_MASK_CALC(timer) & TIMER_CONTROL_PAUSE_MASK)); |
---|
1313 | } |
---|
1314 | |
---|
1315 | void warp_timer_setMode(unsigned char timer, unsigned char mode) { |
---|
1316 | if(mode == 1) |
---|
1317 | warp_timer_WriteReg_control(warp_timer_ReadReg_control() | (TIMER_MASK_CALC(timer) & TIMER_CONTROL_MODE_MASK)); |
---|
1318 | else |
---|
1319 | warp_timer_WriteReg_control(warp_timer_ReadReg_control() & ~(TIMER_MASK_CALC(timer) & TIMER_CONTROL_MODE_MASK)); |
---|
1320 | } |
---|
1321 | |
---|
1322 | void warp_timer_resetDone(unsigned char timer) { |
---|
1323 | warp_timer_WriteReg_control(warp_timer_ReadReg_control() | (TIMER_MASK_CALC(timer) & TIMER_CONTROL_RESETDONE_MASK)); |
---|
1324 | warp_timer_WriteReg_control(warp_timer_ReadReg_control() & ~(TIMER_MASK_CALC(timer) & TIMER_CONTROL_RESETDONE_MASK)); |
---|
1325 | } |
---|
1326 | |
---|
1327 | void warp_timer_resetAllDoneStatus() { |
---|
1328 | warp_timer_WriteReg_control(warp_timer_ReadReg_control() | (TIMER_CONTROL_RESETDONE_MASK)); |
---|
1329 | warp_timer_WriteReg_control(warp_timer_ReadReg_control() & ~(TIMER_CONTROL_RESETDONE_MASK)); |
---|
1330 | } |
---|
1331 | |
---|
1332 | void warp_timer_setTimer(unsigned char timer, unsigned int slotTime, unsigned int slotCount) { |
---|
1333 | switch(timer) { |
---|
1334 | case 0: |
---|
1335 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER0_SLOTCOUNT, (Xuint32)(slotCount)); |
---|
1336 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS01_SLOTTIME, ( (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS01_SLOTTIME) & 0xFFFF0000) | slotTime) ); |
---|
1337 | return; |
---|
1338 | case 1: |
---|
1339 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER1_SLOTCOUNT, (Xuint32)(slotCount)); |
---|
1340 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS01_SLOTTIME, ( (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS01_SLOTTIME) & 0x0000FFFF) | (slotTime<<16) ) ); |
---|
1341 | return; |
---|
1342 | case 2: |
---|
1343 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER2_SLOTCOUNT, (Xuint32)(slotCount)); |
---|
1344 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS23_SLOTTIME, ( (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS23_SLOTTIME) & 0xFFFF0000) | slotTime) ); |
---|
1345 | return; |
---|
1346 | case 3: |
---|
1347 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER3_SLOTCOUNT, (Xuint32)(slotCount)); |
---|
1348 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS23_SLOTTIME, ( (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS23_SLOTTIME) & 0x0000FFFF) | (slotTime<<16) ) ); |
---|
1349 | return; |
---|
1350 | case 4: |
---|
1351 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER4_SLOTCOUNT, (Xuint32)(slotCount)); |
---|
1352 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS45_SLOTTIME, ( (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS45_SLOTTIME) & 0xFFFF0000) | slotTime) ); |
---|
1353 | return; |
---|
1354 | case 5: |
---|
1355 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER5_SLOTCOUNT, (Xuint32)(slotCount)); |
---|
1356 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS45_SLOTTIME, ( (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS45_SLOTTIME) & 0x0000FFFF) | (slotTime<<16) ) ); |
---|
1357 | return; |
---|
1358 | case 6: |
---|
1359 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER6_SLOTCOUNT, (Xuint32)(slotCount)); |
---|
1360 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS67_SLOTTIME, ( (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS67_SLOTTIME) & 0xFFFF0000) | slotTime) ); |
---|
1361 | return; |
---|
1362 | case 7: |
---|
1363 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER7_SLOTCOUNT, (Xuint32)(slotCount)); |
---|
1364 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS67_SLOTTIME, ( (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMERS67_SLOTTIME) & 0x0000FFFF) | (slotTime<<16) ) ); |
---|
1365 | return; |
---|
1366 | default: |
---|
1367 | return; |
---|
1368 | } |
---|
1369 | } |
---|
1370 | |
---|
1371 | unsigned char warp_timer_getStatus(unsigned char timer) { |
---|
1372 | return (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER_STATUS) >> (timer*4)) & 0xf; |
---|
1373 | } |
---|
1374 | |
---|
1375 | unsigned char warp_timer_isDone(unsigned char timer) { |
---|
1376 | return (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER_STATUS) & TIMER_MASK_CALC(timer) & TIMER_STATUS_DONE_MASK) != 0; |
---|
1377 | } |
---|
1378 | |
---|
1379 | unsigned char warp_timer_isActive(unsigned char timer) { |
---|
1380 | return (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER_STATUS) & TIMER_MASK_CALC(timer) & TIMER_STATUS_RUNNING_MASK) != 0; |
---|
1381 | } |
---|
1382 | |
---|
1383 | unsigned char warp_timer_isPaused(unsigned char timer) { |
---|
1384 | return (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER_STATUS) & TIMER_MASK_CALC(timer) & TIMER_STATUS_PASUED_MASK) != 0; |
---|
1385 | } |
---|
1386 | |
---|
1387 | unsigned int warp_timer_getStatuses() { |
---|
1388 | return XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER_STATUS); |
---|
1389 | } |
---|
1390 | |
---|
1391 | unsigned char warp_timer_getDoneStatus() { |
---|
1392 | return (XIo_In32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER_STATUS) & TIMER_STATUS_DONE_MASK); |
---|
1393 | } |
---|
1394 | |
---|
1395 | void warp_timer_init(){ |
---|
1396 | //Clear all start/pause/mode/donereset bits |
---|
1397 | XIo_Out32(XPAR_WARP_TIMER_PLBW_0_MEMMAP_TIMER_CONTROL, 0); |
---|
1398 | |
---|
1399 | //Set sane values for the slot times and slot counts |
---|
1400 | warp_timer_setTimer(0, 500, 32); |
---|
1401 | warp_timer_setTimer(1, 500, 32); |
---|
1402 | warp_timer_setTimer(2, 500, 32); |
---|
1403 | warp_timer_setTimer(3, 500, 32); |
---|
1404 | warp_timer_setTimer(4, 500, 32); |
---|
1405 | warp_timer_setTimer(5, 500, 32); |
---|
1406 | warp_timer_setTimer(6, 500, 32); |
---|
1407 | warp_timer_setTimer(7, 500, 32); |
---|
1408 | |
---|
1409 | //Clear any stale timer-done status bits |
---|
1410 | warp_timer_resetAllDoneStatus(); |
---|
1411 | return; |
---|
1412 | } |
---|
1413 | /******* END WARP Timer core control functions *******/ |
---|
1414 | |
---|
1415 | ///@brief Set the transmit power (via the radio's RF VGA) |
---|
1416 | ///@param txPwr Desired transmit power; must be integer in [0,63] |
---|
1417 | ///@return Returns -1 if an invalid power is requested; 0 on success |
---|
1418 | int warpphy_setTxPower(unsigned char txPwr) |
---|
1419 | { |
---|
1420 | if(txPwr > 63) |
---|
1421 | return -1; |
---|
1422 | else |
---|
1423 | WarpRadio_v1_SetTxGainTiming(FIRST_RADIO | SECOND_RADIO, (0x3F & txPwr), 0xF, 1); |
---|
1424 | |
---|
1425 | return 0; |
---|
1426 | } |
---|
1427 | |
---|
1428 | void warpphy_setAutoCorrDetParams(unsigned short corrThresh, unsigned short energyThresh) { |
---|
1429 | ofdm_txrx_mimo_WriteReg_Rx_PktDetCorr_params(corrThresh, energyThresh); |
---|
1430 | return; |
---|
1431 | } |
---|
1432 | |
---|
1433 | void warpphy_setLongCorrThresh(unsigned short thresh) { |
---|
1434 | pktDet_carrierSenseThresh = thresh; |
---|
1435 | XIo_Out32(XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_RX_PKTDET_LONGCORR_THRESHOLDS, thresh); |
---|
1436 | } |
---|
1437 | |
---|
1438 | void warpphy_setCarrierSenseThresh(unsigned short thresh) { |
---|
1439 | longCorrThresh = thresh; |
---|
1440 | ofdm_txrx_mimo_WriteReg_Rx_CSMA_setThresh(pktDet_carrierSenseThresh); |
---|
1441 | } |
---|
1442 | |
---|
1443 | void warpphy_setEnergyDetThresh(unsigned short thresh) { |
---|
1444 | pktDet_energyThresh = thresh; |
---|
1445 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setThresh(thresh); |
---|
1446 | } |
---|
1447 | |
---|
1448 | |
---|
1449 | void warpphy_setAntBPreambleShift(unsigned char shift) |
---|
1450 | { |
---|
1451 | mimo_ofdmTx_setControlBits( (mimo_ofdmTx_getOptions() & ~(0xF0)) | ((shift&0xF)<<4) ); |
---|
1452 | } |
---|
1453 | |
---|
1454 | /*********************************************************************/ |
---|
1455 | /* A whole bunch of debugging functions - these will go away someday */ |
---|
1456 | /*********************************************************************/ |
---|
1457 | |
---|
1458 | #if INCLUDE_WARPPHY_DEBUG_FUNCTIONS |
---|
1459 | |
---|
1460 | void warpphy_incrementTxScaling(int incr_preamble, int incr_payload) |
---|
1461 | { |
---|
1462 | txScaling_preamble += incr_preamble; |
---|
1463 | txScaling_payload += incr_payload; |
---|
1464 | mimo_ofdmTx_setTxScaling(txScaling_preamble, txScaling_payload); |
---|
1465 | xil_printf("TxScaling: Preamble = %d\tPayload = %d\r\n", txScaling_preamble, txScaling_payload); |
---|
1466 | return; |
---|
1467 | } |
---|
1468 | |
---|
1469 | |
---|
1470 | void warpphy_setPktDlyPlus(){ |
---|
1471 | ofdmRx_pktDetDly++; |
---|
1472 | xil_printf("+ofdmRx_pktDetDly = %d\r\n", ofdmRx_pktDetDly); |
---|
1473 | mimo_ofdmRx_setPktDetDly(ofdmRx_pktDetDly); |
---|
1474 | } |
---|
1475 | void warpphy_setPktDlyMinus(){ |
---|
1476 | ofdmRx_pktDetDly--; |
---|
1477 | xil_printf("-ofdmRx_pktDetDly = %d\r\n", ofdmRx_pktDetDly); |
---|
1478 | mimo_ofdmRx_setPktDetDly(ofdmRx_pktDetDly); |
---|
1479 | } |
---|
1480 | |
---|
1481 | /*********************/ |
---|
1482 | /* Other PHY options */ |
---|
1483 | /*********************/ |
---|
1484 | |
---|
1485 | void warpphy_set_FFTOffset_Plus(){ |
---|
1486 | RxFFT_Window_Offset++; |
---|
1487 | mimo_ofdmRx_setFFTWindowOffset(RxFFT_Window_Offset); |
---|
1488 | xil_printf("Rx FFT Offset: %d\r\n", RxFFT_Window_Offset); |
---|
1489 | } |
---|
1490 | |
---|
1491 | void warpphy_set_FFTOffset_Minus(){ |
---|
1492 | RxFFT_Window_Offset--; |
---|
1493 | mimo_ofdmRx_setFFTWindowOffset(RxFFT_Window_Offset); |
---|
1494 | xil_printf("Rx FFT Offset: %d\r\n", RxFFT_Window_Offset); |
---|
1495 | } |
---|
1496 | |
---|
1497 | void warpphy_setNoiseTargetPlus(){ |
---|
1498 | agc_noisePowerEstimate++; |
---|
1499 | xil_printf("+Noise Estimate = %d\r\n", agc_noisePowerEstimate); |
---|
1500 | ofdm_AGC_setNoiseEstimate(agc_noisePowerEstimate); |
---|
1501 | } |
---|
1502 | |
---|
1503 | void warpphy_setNoiseTargetMinus(){ |
---|
1504 | agc_noisePowerEstimate--; |
---|
1505 | xil_printf("-Noise Estimate = %d\r\n", agc_noisePowerEstimate); |
---|
1506 | ofdm_AGC_setNoiseEstimate(agc_noisePowerEstimate); |
---|
1507 | } |
---|
1508 | |
---|
1509 | void warpphy_setTargetPlus(){ |
---|
1510 | agc_targetRxPowerOut++; |
---|
1511 | xil_printf("+agc_targetRxPowerOut = %d\r\n", agc_targetRxPowerOut); |
---|
1512 | ofdm_AGC_SetTarget(agc_targetRxPowerOut); |
---|
1513 | } |
---|
1514 | |
---|
1515 | void warpphy_setTargetMinus(){ |
---|
1516 | agc_targetRxPowerOut--; |
---|
1517 | xil_printf("-agc_targetRxPowerOut = %d\r\n", agc_targetRxPowerOut); |
---|
1518 | ofdm_AGC_SetTarget(agc_targetRxPowerOut); |
---|
1519 | } |
---|
1520 | |
---|
1521 | void warpphy_setPktDetPlus(unsigned int offset){ |
---|
1522 | pktDet_energyThresh=pktDet_energyThresh+offset; |
---|
1523 | //ofdm_pktDetector_mimo_WriteReg_pktDet_avgThresh(PKTDET_BASEADDR, pktDet_energyThresh); |
---|
1524 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setThresh(pktDet_energyThresh); |
---|
1525 | xil_printf("pktDet_energyThresh = %d\r\n",pktDet_energyThresh); |
---|
1526 | } |
---|
1527 | |
---|
1528 | void warpphy_setPktDetMinus(unsigned int offset){ |
---|
1529 | pktDet_energyThresh=pktDet_energyThresh-offset; |
---|
1530 | //ofdm_pktDetector_mimo_WriteReg_pktDet_avgThresh(PKTDET_BASEADDR, pktDet_energyThresh); |
---|
1531 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setThresh(pktDet_energyThresh); |
---|
1532 | |
---|
1533 | xil_printf("pktDet_energyThresh = %d\r\n",pktDet_energyThresh); |
---|
1534 | } |
---|
1535 | |
---|
1536 | void warpphy_setPktDetMinDurPlus(unsigned int offset){ |
---|
1537 | pktDet_threshMinDur = pktDet_threshMinDur + offset; |
---|
1538 | |
---|
1539 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setMinDuration(pktDet_threshMinDur); |
---|
1540 | xil_printf("Minimum Duration = %d\r\n", pktDet_threshMinDur); |
---|
1541 | } |
---|
1542 | |
---|
1543 | void warpphy_setPktDetMinDurMinus(unsigned int offset){ |
---|
1544 | pktDet_threshMinDur = pktDet_threshMinDur - offset; |
---|
1545 | |
---|
1546 | ofdm_txrx_mimo_WriteReg_Rx_PktDet_setMinDuration(pktDet_threshMinDur); |
---|
1547 | xil_printf("Minimum Duration = %d\r\n", pktDet_threshMinDur); |
---|
1548 | } |
---|
1549 | |
---|
1550 | void warpphy_setCSMAPlus(unsigned int offset){ |
---|
1551 | pktDet_carrierSenseThresh = pktDet_carrierSenseThresh + offset; |
---|
1552 | |
---|
1553 | ofdm_txrx_mimo_WriteReg_Rx_CSMA_setThresh(pktDet_carrierSenseThresh); |
---|
1554 | xil_printf("Carrier Sense Thresh = %d\r\n", pktDet_carrierSenseThresh); |
---|
1555 | } |
---|
1556 | |
---|
1557 | void warpphy_setCSMAMinus(unsigned int offset){ |
---|
1558 | pktDet_carrierSenseThresh = pktDet_carrierSenseThresh - offset; |
---|
1559 | |
---|
1560 | ofdm_txrx_mimo_WriteReg_Rx_CSMA_setThresh(pktDet_carrierSenseThresh); |
---|
1561 | xil_printf("Carrier Sense Thresh = %d\r\n", pktDet_carrierSenseThresh); |
---|
1562 | } |
---|
1563 | |
---|
1564 | void warpphy_setGainPlus(unsigned int offset){ |
---|
1565 | txGain=txGain+offset; |
---|
1566 | WarpRadio_v1_SetTxGainTiming(FIRST_RADIO | SECOND_RADIO, txGain, 0xF, 2); |
---|
1567 | xil_printf("TxGain = %x\r\n",txGain); |
---|
1568 | } |
---|
1569 | |
---|
1570 | void warpphy_setGainMinus(unsigned int offset){ |
---|
1571 | txGain=txGain-offset; |
---|
1572 | WarpRadio_v1_SetTxGainTiming(FIRST_RADIO | SECOND_RADIO, txGain, 0xF, 2); |
---|
1573 | xil_printf("TxGain = %x\r\n",txGain); |
---|
1574 | } |
---|
1575 | |
---|
1576 | |
---|
1577 | #endif |
---|
1578 | |
---|