source: ResearchApps/PHY/WARPLAB/WARPLab7/C_Code_Reference/wl_interface.c

Last change on this file was 4989, checked in by chunter, 8 years ago

Added a new command, rx_lpf_corn_freq_fine, to adjust another parameter in the radio controller

File size: 19.7 KB
RevLine 
[4196]1/** @file wl_interface.c
2 *  @brief WARPLab Framework (Interface)
3 *
4 *  This contains the code for WARPLab Framework.
5 *
[4668]6 *  @copyright Copyright 2013-2015, Mango Communications. All rights reserved.
[4196]7 *          Distributed under the WARP license  (http://warpproject.org/license)
8 *
9 *  @author Chris Hunter (chunter [at] mangocomm.com)
10 *  @author Patrick Murphy (murphpo [at] mangocomm.com)
11 *  @author Erik Welsh (welsh [at] mangocomm.com)
12 */
[1995]13
[4453]14
15/**********************************************************************************************************************/
16/**
[4668]17 * @brief Common Functions
[4453]18 *
19 **********************************************************************************************************************/
20
21
[4196]22/***************************** Include Files *********************************/
[1915]23
[4196]24// Xilinx / Standard library includes
[1915]25#include <xparameters.h>
[4196]26#include <xio.h>
27
[1915]28#include <stdlib.h>
29#include <stdio.h>
[4196]30
31// Xilinx Peripheral includes
[1915]32#include <radio_controller.h>
33
[4196]34// WARPLab includes
35#include "wl_common.h"
36#include "wl_interface.h"
37#include "wl_baseband.h"
38
[2013]39
40
[4196]41/*************************** Constant Definitions ****************************/
[1915]42
[4196]43/*********************** Global Variable Definitions *************************/
[1915]44
[4196]45/*************************** Variable Definitions ****************************/
[1915]46
[4196]47/*************************** Functions Prototypes ****************************/
[1915]48
[4196]49/******************************** Functions **********************************/
[1915]50
[4284]51/*****************************************************************************/
52/**
[4514]53 * Process Interface Commands
54 *
55 * This function is part of the Ethernet processing system and will process the
56 * various interface related commands.
57 *
58 * @param   socket_index     - Index of the socket on which to send message
59 * @param   from             - Pointer to socket address structure (struct sockaddr *) where command is from
60 * @param   command          - Pointer to WARPLab Command
61 * @param   response         - Pointer to WARPLab Response
62 *
[4668]63 * @return  int              - Status of the command:
64 *                                 NO_RESP_SENT - No response has been sent
65 *                                 RESP_SENT    - A response has been sent
[4514]66 *
67 * @note    See on-line documentation for more information about the Ethernet
68 *          packet structure for WARPLab:  www.warpproject.org
69 *
70 ******************************************************************************/
71int ifc_process_cmd(int socket_index, void * from, wl_cmd_resp * command, wl_cmd_resp * response) {
[1915]72
[4668]73    //
[4514]74    // IMPORTANT ENDIAN NOTES:
[4668]75    //     - command
76    //         - header - Already endian swapped by the framework (safe to access directly)
77    //         - args   - Must be endian swapped as necessary by code (framework does not know the contents of the command)
78    //     - response
79    //         - header - Will be endian swapped by the framework (safe to write directly)
80    //         - args   - Must be endian swapped as necessary by code (framework does not know the contents of the response)
81    //
[1915]82
[4668]83    // Standard variables
[4514]84    u32                 resp_sent      = NO_RESP_SENT;
[1942]85
[4514]86    wl_cmd_resp_hdr   * cmd_hdr        = command->header;
87    u32               * cmd_args_32    = command->args;
88    u32                 cmd_id         = WL_CMD_TO_CMDID(cmd_hdr->cmd);
[4284]89
[4514]90    wl_cmd_resp_hdr   * resp_hdr       = response->header;
[4684]91    u32               * resp_args_32   = response->args;
92    u32                 resp_index     = 0;
[4514]93
94    // Specific command variables
[4668]95    u32                 rf_sel;
[4684]96    u32                 rf_enable;
97    u32                 rf_state;
[4668]98    u32                 band, chan;
99    u32                 bb_gain, rf_gain;
100    u32                 enable;
[4673]101    u8                  corn_freq;
[4514]102
[4759]103    u32                 rxhp_val;
104    u32                 rxhp_en;
105
[4668]106    // Set up the response header
107    resp_hdr->cmd       = cmd_hdr->cmd;
108    resp_hdr->length    = 0;
109    resp_hdr->num_args  = 0;
[1915]110
[4668]111    // Process the command
112    switch(cmd_id){
[4196]113
[4668]114        //---------------------------------------------------------------------
[4783]115        case CMDID_INTERFACE_TX_EN:
[4668]116            // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Tx enable\n");
[1915]117
[4668]118            rf_sel = Xil_Ntohl(cmd_args_32[0]);
119            radio_controller_TxEnable(RC_BASEADDR, rf_sel);
120        break;
[1915]121
122
[4668]123        //---------------------------------------------------------------------
[4783]124        case CMDID_INTERFACE_RX_EN:
[4668]125            // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Rx enable\n");
[1915]126
[4668]127            rf_sel = Xil_Ntohl(cmd_args_32[0]);
128            radio_controller_RxEnable(RC_BASEADDR, rf_sel);
129        break;
[1915]130
[1995]131
[4668]132        //---------------------------------------------------------------------
[4783]133        case CMDID_INTERFACE_TXRX_DIS:
[4668]134            // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Tx/Rx disable\n");
[1995]135
[4668]136            rf_sel =  Xil_Ntohl(cmd_args_32[0]);
137            radio_controller_TxRxDisable(RC_BASEADDR, rf_sel);
138        break;
[1915]139
[1995]140
[4668]141        //---------------------------------------------------------------------
[4783]142        case CMDID_INTERFACE_TXRX_STATE:
[4684]143            // Return the state of the TX and RX interface
144            //
145            // Message format:
146            //     cmd_args_32[0]      Interface Select (bit selects):
147            //                             - [28]     - Select RF A interface
148            //                             - [29]     - Select RF B interface
149            //                             - [30]     - Select RF C interface
150            //                             - [31]     - Select RF D interface
[4820]151            //
[4684]152            // Response format:
153            //     resp_args_32[0]     RF A state (optional)
154            //     resp_args_32[1]     RF B state (optional)
155            //     resp_args_32[2]     RF C state (optional)
156            //     resp_args_32[3]     RF D state (optional)
157            //
[4820]158            // NOTE:  The return value of the RF state will only get added to the return
159            //     arguments if the given RF interface is selected.
[4684]160            //
[4820]161            rf_sel   = Xil_Ntohl(cmd_args_32[0]);
162            rf_state = wl_get_radio_controller_state();
[4684]163
164            if (rf_sel & RC_RFA) {
[4820]165                rf_enable = RF_STATE_STANDBY;
[4684]166
167                if (rf_state & RF_RX_ANT_A) { rf_enable = RF_STATE_RX; }
168                if (rf_state & RF_TX_ANT_A) { rf_enable = RF_STATE_TX; }
169
170                resp_args_32[resp_index++] = Xil_Htonl(rf_enable);
171            }
172
173            if (rf_sel & RC_RFB) {
[4820]174                rf_enable = RF_STATE_STANDBY;
[4684]175
176                if (rf_state & RF_RX_ANT_B) { rf_enable = RF_STATE_RX; }
177                if (rf_state & RF_TX_ANT_B) { rf_enable = RF_STATE_TX; }
178
179                resp_args_32[resp_index++] = Xil_Htonl(rf_enable);
180            }
181
182            if (rf_sel & RC_RFC) {
[4820]183                rf_enable = RF_STATE_STANDBY;
[4684]184
185                if (rf_state & RF_RX_ANT_C) { rf_enable = RF_STATE_RX; }
186                if (rf_state & RF_TX_ANT_C) { rf_enable = RF_STATE_TX; }
187
188                resp_args_32[resp_index++] = Xil_Htonl(rf_enable);
189            }
190
191            if (rf_sel & RC_RFD) {
[4820]192                rf_enable = RF_STATE_STANDBY;
[4684]193
194                if (rf_state & RF_RX_ANT_D) { rf_enable = RF_STATE_RX; }
195                if (rf_state & RF_TX_ANT_D) { rf_enable = RF_STATE_TX; }
196
197                resp_args_32[resp_index++] = Xil_Htonl(rf_enable);
198            }
199
200            // Send response
201            resp_hdr->length  += (resp_index * sizeof(resp_args_32));
202            resp_hdr->num_args = resp_index;
203        break;
204
205
206        //---------------------------------------------------------------------
[4783]207        case CMDID_INTERFACE_CHANNEL:
[4668]208            // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Set channel\n");
[1915]209
[4668]210            rf_sel = Xil_Ntohl(cmd_args_32[0]);
211            band   = Xil_Ntohl(cmd_args_32[1]);
212            chan   = Xil_Ntohl(cmd_args_32[2]);
[1915]213
[4668]214            radio_controller_setCenterFrequency(RC_BASEADDR, rf_sel, band, chan);
215        break;
[1915]216
[4184]217
[4668]218        //---------------------------------------------------------------------
[4783]219        case CMDID_INTERFACE_TX_GAINS:
[4668]220            // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Set Tx gains\n");
[4184]221
[4668]222            rf_sel  = Xil_Ntohl(cmd_args_32[0]);
223            bb_gain = Xil_Ntohl(cmd_args_32[1]);
224            rf_gain = Xil_Ntohl(cmd_args_32[2]);
[4184]225
[4668]226            radio_controller_setRadioParam(RC_BASEADDR, rf_sel, RC_PARAMID_TXGAIN_BB, bb_gain);
227            radio_controller_setRadioParam(RC_BASEADDR, rf_sel, RC_PARAMID_TXGAIN_RF, rf_gain);
228        break;
[4184]229
230
[4668]231        //---------------------------------------------------------------------
[4783]232        case CMDID_INTERFACE_RX_GAINS:
[4668]233            // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Set Rx gains\n");
[4184]234
[4668]235            rf_sel  = Xil_Ntohl(cmd_args_32[0]);
236            rf_gain = Xil_Ntohl(cmd_args_32[1]);
237            bb_gain = Xil_Ntohl(cmd_args_32[2]);
[4184]238
[4759]239            // Get the current RXHP value
240            rxhp_val = (Xil_In32(RC_BASEADDR + RC_SLV_REG0_OFFSET) & RC_REG0_RXHP);
241
242            // Force RXHP to one
243            //   - This will minimize the impact of DC level changes during RX gain changes
244            //
245            radio_controller_setRxHP(RC_BASEADDR, rf_sel, RC_RXHP_ON);
246
[4668]247            radio_controller_setRadioParam(RC_BASEADDR, rf_sel, RC_PARAMID_RXGAIN_RF, rf_gain);
248            radio_controller_setRadioParam(RC_BASEADDR, rf_sel, RC_PARAMID_RXGAIN_BB, bb_gain);
[4759]249
250            // Set RXHP back to the original value
[4783]251            if(rf_sel & RC_RFA) {
252                rxhp_en = (rxhp_val & RC_CTRLREGMASK_RFA) ? RC_RXHP_ON : RC_RXHP_OFF;
[4759]253                radio_controller_setRxHP(RC_BASEADDR, RC_RFA, rxhp_en);
[4783]254            }
255            if(rf_sel & RC_RFB) {
256                rxhp_en = (rxhp_val & RC_CTRLREGMASK_RFB) ? RC_RXHP_ON : RC_RXHP_OFF;
[4759]257                radio_controller_setRxHP(RC_BASEADDR, RC_RFB, rxhp_en);
[4783]258            }
259            if(rf_sel & RC_RFC) {
260                rxhp_en = (rxhp_val & RC_CTRLREGMASK_RFC) ? RC_RXHP_ON : RC_RXHP_OFF;
[4759]261                radio_controller_setRxHP(RC_BASEADDR, RC_RFC, rxhp_en);
[4783]262            }
263            if(rf_sel & RC_RFD) {
264                rxhp_en = (rxhp_val & RC_CTRLREGMASK_RFD) ? RC_RXHP_ON : RC_RXHP_OFF;
[4759]265                radio_controller_setRxHP(RC_BASEADDR, RC_RFD, rxhp_en);
[4783]266            }
[4668]267        break;
[4184]268
269
[4668]270        //---------------------------------------------------------------------
[4783]271        case CMDID_INTERFACE_TX_LPF_CORN_FREQ:
[4668]272            // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Set Tx LPF corner freq\n");
[4184]273
[4673]274            rf_sel      = Xil_Ntohl(cmd_args_32[0]);
275            corn_freq   = Xil_Ntohl(cmd_args_32[1]);
[4184]276
[4673]277            radio_controller_setRadioParam(RC_BASEADDR, rf_sel, RC_PARAMID_TXLPF_BW, corn_freq);
[4668]278        break;
[4184]279
280
[4668]281        //---------------------------------------------------------------------
[4783]282        case CMDID_INTERFACE_RX_LPF_CORN_FREQ:
[4668]283            // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Set Rx LPF corner freq\n");
[4184]284
[4673]285            rf_sel      = Xil_Ntohl(cmd_args_32[0]);
286            corn_freq   = Xil_Ntohl(cmd_args_32[1]);
[4184]287
[4673]288            radio_controller_setRadioParam(RC_BASEADDR, rf_sel, RC_PARAMID_RXLPF_BW, corn_freq);
[4668]289        break;
[4184]290
[4989]291        //---------------------------------------------------------------------
292        case CMDID_INTERFACE_RX_LPF_CORN_FREQ_FINE:
293            // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Set Rx LPF corner freq\n");
[4184]294
[4989]295            rf_sel      = Xil_Ntohl(cmd_args_32[0]);
296            corn_freq   = Xil_Ntohl(cmd_args_32[1]);
297
298            radio_controller_setRadioParam(RC_BASEADDR, rf_sel, RC_PARAMID_RXLPF_BW_FINE, corn_freq);
299        break;
300
[4668]301        //---------------------------------------------------------------------
[4783]302        case CMDID_INTERFACE_RX_HPF_CORN_FREQ:
[4673]303            // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Set Rx HPF corner freq\n");
304
305            rf_sel      = Xil_Ntohl(cmd_args_32[0]);
306            corn_freq   = Xil_Ntohl(cmd_args_32[1]);
307
308
309            xil_printf("HPF CORN FREQ:  0x%08x    0x%08x\n", rf_sel, corn_freq);
310
311
312            //
313            // NOTE:  The setting of the RX HPF cutoff frequency only take effect if RXHP is 0.  Unfortunately,
314            //     we are not able to read the read the RXHP value to determine if this write actually takes
315            //     effect when we perform the setRadioParam function.  Therefore it is left up to the user to
316            //     make sure the state of the radio controller is correct to have this command take effect.
317            //
318
319            radio_controller_setRadioParam(RC_BASEADDR, rf_sel, RC_PARAMID_RXHPF_HIGH_CUTOFF_EN, corn_freq);
320        break;
321
322
323        //---------------------------------------------------------------------
[4783]324        case CMDID_INTERFACE_RX_GAIN_CTRL_SRC:
[4668]325            // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Set gain control source\n");
[4184]326
[4668]327            rf_sel = Xil_Ntohl(cmd_args_32[0]);
328            enable = Xil_Ntohl(cmd_args_32[1]) & 0x1;
[4184]329
[4668]330            if (enable == 0){
331                // Manual gain control
332                //   NOTE:  AGC will always run but values will be ignored
333                radio_controller_setCtrlSource(RC_BASEADDR, rf_sel, RC_REG0_RXHP_CTRLSRC, RC_CTRLSRC_REG);
334                radio_controller_setRxGainSource(RC_BASEADDR, rf_sel, RC_GAINSRC_SPI);
[4184]335
[4668]336                // De-select AGC I/Q signals for Rx buffers input and disable buffers->AGC trigger
[4797]337                wl_bb_clear_config(rf_sel >> 24);
[4668]338            } else {
339                // Automatic gain control
340                radio_controller_setCtrlSource(RC_BASEADDR, rf_sel, RC_REG0_RXHP_CTRLSRC, RC_CTRLSRC_HW);
341                radio_controller_setRxGainSource(RC_BASEADDR, rf_sel, RC_GAINSRC_HW);
[4184]342
[4668]343                // Select AGC I/Q signals for Rx buffers input and enable buffers->AGC trigger
344                wl_bb_set_config(rf_sel >> 24);
345            }
[4184]346
[4668]347        break;
[4184]348
[4331]349
[4668]350        //---------------------------------------------------------------------
[4783]351        case CMDID_INTERFACE_RXHP_CTRL:
[4668]352            // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Set rxhp value\n");
[4331]353
[4668]354            rf_sel = Xil_Ntohl(cmd_args_32[0]);
355            enable = Xil_Ntohl(cmd_args_32[1]) & 0x1;
[4331]356
[4668]357            if(enable == 0){
358                // Force RXHP to zero
359                radio_controller_setRxHP(RC_BASEADDR, rf_sel, RC_RXHP_OFF);
360            } else {
361                // Force RXHP to one
362                radio_controller_setRxHP(RC_BASEADDR, rf_sel, RC_RXHP_ON);
363            }
[4331]364
[4668]365        break;
[4331]366
[4668]367
368        //---------------------------------------------------------------------
369        default:
370            wl_printf(WL_PRINT_ERROR, print_type_interface, "Unknown command ID: %d\n", cmd_id);
371        break;
372    }
373    return resp_sent;
[1915]374}
375
376
[4184]377
[4284]378/*****************************************************************************/
379/**
[4453]380 * @brief Set Radio Controller defaults
381 *
382 * @param  None
[4668]383 *
[4453]384 * @return None
[4668]385 *
[4453]386 ******************************************************************************/
387void set_radio_controller_defaults(u32 all_rf_sel) {
388
[4668]389    // Set Tx bandwidth to nominal mode (Radios_Tx_LPF_Corn_Freq)
390    radio_controller_setRadioParam(RC_BASEADDR, all_rf_sel, RC_PARAMID_TXLPF_BW, 1);
[4453]391
[4668]392    // Set Rx bandwidth to nominal mode (Radios_Rx_LPF_Corn_Freq)
393    radio_controller_setRadioParam(RC_BASEADDR, all_rf_sel, RC_PARAMID_RXLPF_BW, 1);
[4989]394    radio_controller_setRadioParam(RC_BASEADDR, all_rf_sel, RC_PARAMID_RXLPF_BW_FINE, 2);
[4453]395
[4668]396    // Set Radios to use 30KHz cutoff on HPF
397    radio_controller_setRadioParam(RC_BASEADDR, all_rf_sel, RC_PARAMID_RXHPF_HIGH_CUTOFF_EN, 1);
[4673]398
399    // Set Tx VGA Linearity to 2 (78% current) see pg 36 of MAX2829 datasheet for more information
[4668]400    radio_controller_setRadioParam(RC_BASEADDR, all_rf_sel, RC_PARAMID_TXLINEARITY_VGA, 2);
[4673]401
402    // Disable all Tx / Rx
[4668]403    radio_controller_TxRxDisable(RC_BASEADDR, all_rf_sel);
[4453]404
405}
406
407
408
409
410/**********************************************************************************************************************/
411/**
412 * @brief WARP v3 Specific Functions
413 *
414 **********************************************************************************************************************/
415
416/***************************** Include Files *********************************/
417
418#include <w3_ad_controller.h>
419
420/*************************** Constant Definitions ****************************/
421
422/*********************** Global Variable Definitions *************************/
423
424/*************************** Variable Definitions ****************************/
425
426/*************************** Functions Prototypes ****************************/
427
428/******************************** Functions **********************************/
429
430/*****************************************************************************/
431/**
[4284]432 * @brief RF Interface subsystem initialization
433 *
434 * Initializes the RF interface subsystem
435 *
436 * @param  None
437 *
[4668]438 * @return  int              - Status of the command:
439 *                                 XST_SUCCESS - Command completed successfully
440 *                                 XST_FAILURE - There was an error in the command
441 *
[4284]442 ******************************************************************************/
[1915]443int ifc_init(){
[4668]444    // wl_printf(WL_PRINT_DEBUG, print_type_interface, "Configuring interface ...\n\n");
[2033]445
[4668]446    int status          = XST_SUCCESS;
[4196]447    u32 all_rf_sel;
448    u32 all_ad_sel;
[4453]449
[4196]450    // Set the "ALL" variables based on the RF config
451    if (WARPLAB_CONFIG_4RF) {
452        all_rf_sel = (RC_RFA | RC_RFB | RC_RFC | RC_RFD);
453        all_ad_sel = (RFA_AD_CS | RFB_AD_CS | RFC_AD_CS | RFD_AD_CS);
454    } else {
455        all_rf_sel = (RC_RFA | RC_RFB);
456        all_ad_sel = (RFA_AD_CS | RFB_AD_CS);
457    }
[2033]458
[4668]459    // Initialize the AD9963 ADCs/DACs
460    status = ad_init(AD_BASEADDR, all_ad_sel, 2);
[1915]461
[4668]462    if(status != XST_SUCCESS) {
463        wl_printf(WL_PRINT_ERROR, print_type_interface, "AD initialization failed with status: %d\n", status);
464        wl_printf(WL_PRINT_NONE, NULL, "\n************************************************************\n");
465        wl_printf(WL_PRINT_NONE, NULL, " Check that software and hardware config match\n  (this error may indicate 4-radio code on 2-radio hadrware)\n");
466        wl_printf(WL_PRINT_NONE, NULL, "************************************************************\n\n");
467        return XST_FAILURE;
468    }
[4453]469
[4668]470    // Initialize the radio_controller core and MAX2829 transceivers
471    status = radio_controller_init(RC_BASEADDR, (all_rf_sel), 1, 1);
[4196]472
[4668]473    if(status != XST_SUCCESS) {
474        wl_printf(WL_PRINT_ERROR, print_type_interface, "Radio controller initialization failed with status: %d\n", status);
475        return XST_FAILURE;
[4453]476    }
477
[4673]478    // Update the TX delays to match the 802.11 design
479    //     NOTE:  These values considerably reduces any "pop" in the transmission following a TX enable (TX_EN) command
480    //     NOTE:  Default value set in radio_controller_init() is:  radio_controller_setTxDelays(RC_BASEADDR, 150, 0, 0, 250);
481    //
482    radio_controller_setTxDelays(RC_BASEADDR, 40, 20, 0, 250);
483
[4668]484    // Default the Tx/Rx gain control sources to SPI
485    radio_controller_setTxGainSource(RC_BASEADDR, all_rf_sel, RC_GAINSRC_SPI);
486    radio_controller_setRxGainSource(RC_BASEADDR, all_rf_sel, RC_GAINSRC_SPI);
[4453]487
[4668]488    // Apply the TxDCO correction values stored in the on-board (and FMC, if present) EEPROMs
489    radio_controller_apply_TxDCO_calibration(AD_BASEADDR, EEPROM_BASEADDR, all_rf_sel);
[4453]490
[4668]491    // Set some sane defaults for the MAX2829 Tx/Rx paths; these can be changed by WARPLab commands later
492    set_radio_controller_defaults(all_rf_sel);
[4453]493
[4668]494    return status;
[1915]495}
496
[4453]497
498
Note: See TracBrowser for help on using the repository browser.