//////////////////////////////////////////////////////////////////////////////// // // File : warplab.c v6.3b // Date : 2012, November 16 // Author : P. Murphy, S. Gupta, M. Duarte, C. Hunter // // Changelog: // v6.3 // - No changes to C-code other than the print that says what version it is // - Small bugfixes to UCF for WARP v2 and WARP v3 // v6.2 // - This warplab.c is tailored to WARP v3. It will not compile on other hardware. // - Added support for WARPxilnet_v3_00 that adds support for the hard TEMACs // inside the Virtex4 // - v2 WARP hardware will use gigabit speeds by default. The Ethernet PHY // advertises its speed as gigabit, so there is no longer a need to // explicitly tell your computer to send at 100Mbit. // - Uses an XPS_Timer core to inact a timeout of WAITDURATION_SEC seconds // to wait for a sync packet. Previously, this timeout was handled by // waiting a set number of packets (e.g. 10 received packets). // - Moved the sync IP address up to a proper broadcast address of X.X.X.255. // This should obviate the need for explicit ARP table entries to handle // sync packets. The v06 WARPLAB M-Code Reference has correspondingly been // updated. // - This source file will compile for either v1 or v2 WARP hardware, assuming // the WARPxilnet and WARP_FPGA_BOARD software libraries are configured // //////////////////////////////////////////////////////////////////////////////// #include "xparameters.h" #include #include #include #include "xstatus.h" #include #include #include "math.h" #include "radio_controller.h" #include "warplab_defines.h" #include "warplab_regmacros.h" #include "stdio.h" #include "xtmrctr.h" #include "w3_userio.h" #include "w3_ad_controller.h" #include "w3_clock_controller.h" #include "w3_iic_eeprom.h" #include "Xio.h" #include "xlltemac.h" #include "xllfifo.h" #include "xdmacentral.h" #include "xdmacentral_l.h" #include "warp_hw_ver.h" #define WARPLAB_MAJOR_VER 6 #define WARPLAB_MINOR_VER 3 #define RC_BASEADDR XPAR_RADIO_CONTROLLER_0_BASEADDR #define AD_BASEADDR XPAR_W3_AD_CONTROLLER_0_BASEADDR #define CLK_BASEADDR XPAR_W3_CLOCK_CONTROLLER_0_BASEADDR #define EEPROM_BASEADDR XPAR_W3_IIC_EEPROM_0_BASEADDR #define USERIO_BASEADDR XPAR_W3_USERIO_0_BASEADDR #define TIMER_FREQ XPAR_XPS_TIMER_0_CLOCK_FREQ_HZ #define WARPLAB_TXBUFF_RADIO1 XPAR_WARPLAB_BUFFERS_PLBW_0_MEMMAP_TXBUFF_RADIO1 #define WARPLAB_TXBUFF_RADIO2 XPAR_WARPLAB_BUFFERS_PLBW_0_MEMMAP_TXBUFF_RADIO2 #define WARPLAB_TXBUFF_RADIO3 XPAR_WARPLAB_BUFFERS_PLBW_0_MEMMAP_TXBUFF_RADIO3 #define WARPLAB_TXBUFF_RADIO4 XPAR_WARPLAB_BUFFERS_PLBW_0_MEMMAP_TXBUFF_RADIO4 #define WARPLAB_RXBUFF_RADIO1 XPAR_WARPLAB_BUFFERS_PLBW_0_MEMMAP_RXBUFF_RADIO1 #define WARPLAB_RXBUFF_RADIO2 XPAR_WARPLAB_BUFFERS_PLBW_0_MEMMAP_RXBUFF_RADIO2 #define WARPLAB_RXBUFF_RADIO3 XPAR_WARPLAB_BUFFERS_PLBW_0_MEMMAP_RXBUFF_RADIO3 #define WARPLAB_RXBUFF_RADIO4 XPAR_WARPLAB_BUFFERS_PLBW_0_MEMMAP_RXBUFF_RADIO4 #define WARPLAB_RSSIBUFF_RADIO1 XPAR_WARPLAB_BUFFERS_PLBW_0_MEMMAP_RSSIBUFF_RADIO1 #define WARPLAB_RSSIBUFF_RADIO2 XPAR_WARPLAB_BUFFERS_PLBW_0_MEMMAP_RSSIBUFF_RADIO2 #define WARPLAB_RSSIBUFF_RADIO3 XPAR_WARPLAB_BUFFERS_PLBW_0_MEMMAP_RSSIBUFF_RADIO3 #define WARPLAB_RSSIBUFF_RADIO4 XPAR_WARPLAB_BUFFERS_PLBW_0_MEMMAP_RSSIBUFF_RADIO4 #define TEMAC_DEVICE_ID XPAR_LLTEMAC_0_DEVICE_ID #define FIFO_DEVICE_ID XPAR_LLFIFO_0_DEVICE_ID #define TMRCTR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID #define TIMER_COUNTER_0 0 #define WARPLAB_CONFIG_2RF 1 // Comment in if board in 2x2 configuration //#define WARPLAB_CONFIG_4RF 1 // Comment in if board in 4x4 configuration // Currently not applicable to WARP v3 static XDmaCentral DmaCentralInst; static XDmaCentral_Config *DMAConfigPtr; XLlTemac TemacInstance; XLlTemac_Config *MacCfgPtr; XLlFifo FifoInstance; XTmrCtr TimerCounter; /* The instance of the Tmrctr Device */ u8 numSync; u8 hw_generation; u8 numRadios; #define ENET_LINK_SPEED 1000 #define BUFSIZE 2000 #define DEBUG_LVL 0 #define WAITDURATION_SEC 2 unsigned int sendPtr32[(BUFSIZE+3)/4]; unsigned char * const sendBuffer = (unsigned char *) sendPtr32; unsigned int receivePtr32[(BUFSIZE+3)/4]; unsigned char * const receiveBuffer = (unsigned char *) receivePtr32; unsigned int myPort; int sock; // UDP socket struct sockaddr_in addr; unsigned int alen = 0; char node; unsigned int ReadWrite; unsigned char Radios_WirelessChan; unsigned char Radios_Tx_LPF_Corn_Freq; unsigned char Radios_Rx_LPF_Corn_Freq; unsigned char Radio1_TxGain_BB, Radio1_TxGain_RF, Radio1_RxGain_BB, Radio1_RxGain_RF; unsigned char Radio2_TxGain_BB, Radio2_TxGain_RF, Radio2_RxGain_BB, Radio2_RxGain_RF; unsigned char Radio3_TxGain_BB, Radio3_TxGain_RF, Radio3_RxGain_BB, Radio3_RxGain_RF; unsigned char Radio4_TxGain_BB, Radio4_TxGain_RF, Radio4_RxGain_BB, Radio4_RxGain_RF; unsigned int AgcIsDoneAddr; unsigned int MGC_AGC_Sel_Variable = 0; // By default MGC is selected //---------------------------------- // Functions void sendACK(unsigned int packetNo, unsigned int commandToACK); unsigned char sevenSegmentMap(unsigned char x); int warpphy_applyTxDCOCorrection(unsigned int radioSelection); void warplab_AGC_Reset(); void warplab_AGC_MasterReset(); void warplab_AGC_Start(); void warplab_AGC_Initialize(int noise_estimate); void warplab_AGC_setNoiseEstimate(int noise_estimate); unsigned int warplab_AGC_GetGains(void); void warplab_AGC_SetTarget(unsigned int target); void warplab_AGC_SetDCO(unsigned int AGCstate); int warpphy_applyTxDCOCalibration(unsigned int radioSelection); // In WARPLab there is no decimation filter in the AGC, there is a downsampling only, so in WARPLab a function equivalent to // ofdm_AGC_FiltSel is not needed int w3_node_init() { int status; XTmrCtr *TmrCtrInstancePtr = &TimerCounter; int ret = XST_SUCCESS; microblaze_enable_exceptions(); //Initialize the AD9512 clock buffers (RF reference and sampling clocks) status = clk_init(CLK_BASEADDR, 2); if(status != XST_SUCCESS) { xil_printf("w3_node_init: Error in clk_init (%d)\n", status); ret = XST_FAILURE; } //Update the sampling clock buffer config to divide the AD clocks by 2 for 40MHz sampling clk_spi_write(CLK_BASEADDR, CLKCTRL_REG_SPITX_SAMP_CS, 0x4B, 0x00); //OUT0 divider on clk_spi_write(CLK_BASEADDR, CLKCTRL_REG_SPITX_SAMP_CS, 0x4A, 0x00); //OUT0 divide by 2 clk_spi_write(CLK_BASEADDR, CLKCTRL_REG_SPITX_SAMP_CS, 0x4F, 0x00); //OUT2 divider on clk_spi_write(CLK_BASEADDR, CLKCTRL_REG_SPITX_SAMP_CS, 0x4E, 0x00); //OUT2 divide by 2 clk_spi_write(CLK_BASEADDR, CLKCTRL_REG_SPITX_SAMP_CS, 0x5A, 0x01); //Self-clearing register update flag //Initialize the AD9963 ADCs/DACs status = ad_init(AD_BASEADDR, 2); if(status != XST_SUCCESS) { xil_printf("w3_node_init: Error in ad_init (%d)\n", status); ret = XST_FAILURE; } //Initialize the radio_controller core and MAX2829 transceivers status = radio_controller_init(RC_BASEADDR, (RC_RFA | RC_RFB), 1, 1); if(status != XST_SUCCESS) { xil_printf("w3_node_init: Error in radio_controller_initialize (%d)\n", status); ret = XST_FAILURE; } //Initialize the EEPROM read/write core iic_eeprom_init(EEPROM_BASEADDR, 0x64); if(status != XST_SUCCESS) { xil_printf("w3_node_init: Error in IIC_EEPROM_init (%d)\n", status); ret = XST_FAILURE; } /* * Initialize the timer counter so that it's ready to use, * specify the device ID that is generated in xparameters.h */ status = XTmrCtr_Initialize(TmrCtrInstancePtr, TMRCTR_DEVICE_ID); if (status != XST_SUCCESS) { xil_printf("w3_node_init: Error in XtmrCtr_Initialize (%d)\n", status); ret = XST_FAILURE; } /* * Perform a self-test to ensure that the hardware was built * correctly, use the 1st timer in the device (0) */ status = XTmrCtr_SelfTest(TmrCtrInstancePtr, 0); if (status != XST_SUCCESS) { ret = XST_FAILURE; } // Set timer 0 to into a "count down" mode XTmrCtr_SetOptions(TmrCtrInstancePtr, 0, (XTC_DOWN_COUNT_OPTION)); ///// Project-Specific Initializations ///// node = userio_read_inputs(USERIO_BASEADDR)&W3_USERIO_DIPSW; userio_write_hexdisp_left(USERIO_BASEADDR, (node+1)%10); radio_controller_setTxGainSource(RC_BASEADDR, (RC_RFA | RC_RFB), RC_GAINSRC_SPI); radio_controller_setRxGainSource(RC_BASEADDR, (RC_RFA | RC_RFB), RC_GAINSRC_SPI); radio_controller_apply_TxDCO_calibration(AD_BASEADDR, EEPROM_BASEADDR, (RC_RFA | RC_RFB)); //Set Tx bandwidth to nominal mode Radios_Tx_LPF_Corn_Freq = 1; radio_controller_setRadioParam(RC_BASEADDR, (RC_RFA | RC_RFB), RC_PARAMID_TXLPF_BW, Radios_Tx_LPF_Corn_Freq); //Set Rx bandwidth to nominal mode Radios_Rx_LPF_Corn_Freq = 1; radio_controller_setRadioParam(RC_BASEADDR, (RC_RFA | RC_RFB), RC_PARAMID_RXLPF_BW, Radios_Rx_LPF_Corn_Freq); //Set Radios to use 30KHz cutoff on HPF radio_controller_setRadioParam(RC_BASEADDR, (RC_RFA | RC_RFB), RC_PARAMID_RXHPF_HIGH_CUTOFF_EN, 1); radio_controller_setRadioParam(RC_BASEADDR, (RC_RFA | RC_RFB), RC_PARAMID_TXLINEARITY_VGA, 2); ///Timer Setup/// XTmrCtr_SetResetValue(TmrCtrInstancePtr,1,0); //Sets it so issuing a "start" command begins at counter=0 ///////////////// radio_controller_TxRxDisable(RC_BASEADDR, (RC_RFA | RC_RFB)); #ifdef WARP_HW_VER_v3 hw_generation = 3; #elif defined WARP_HW_VER_v2 hw_generation = 2; #elif defined WARP_HW_VER_v1 hw_generation = 1; #endif #ifdef WARPLAB_CONFIG_2RF numRadios = 2; #elif defined WARPLAB_CONFIG_4RF numRadios = 4; #endif return ret; } void usleep(u32 duration){ XTmrCtr *TmrCtrInstancePtr = &TimerCounter; XTmrCtr_SetResetValue(TmrCtrInstancePtr,0,duration*(TIMER_FREQ/1000000)); XTmrCtr_Start(TmrCtrInstancePtr,0); volatile u8 isExpired = 0; while(isExpired!=1){ isExpired = XTmrCtr_IsExpired(TmrCtrInstancePtr,0); } XTmrCtr_Reset(TmrCtrInstancePtr,0); return; } void init_net() { int Status; xil_printf("Configuring network\n"); mb_hw_addr[0] = 0x00; mb_hw_addr[1] = 0x50; mb_hw_addr[2] = 0xc2; mb_hw_addr[3] = 0x63; mb_hw_addr[4] = 0x36; mb_hw_addr[5] = node+0x63; mb_ip_addr[0] = 10; mb_ip_addr[1] = 0; mb_ip_addr[2] = 0; mb_ip_addr[3] = node+1; //Define the last octet of the IP address used for SYNC packets. The first three will be the mb_ip_addr. sync_IP_octet = 255; myPort = 9000 + node; xilnet_eth_init_hw_addr_tbl(); if(DEBUG_LVL > 1) xil_printf("... initializing DMA\n"); /**************************DMA*******************************/ //Lookup the DMA configuration information DMAConfigPtr = XDmaCentral_LookupConfig(XPAR_XPS_CENTRAL_DMA_0_DEVICE_ID); //Initialize the config struct Status = XDmaCentral_CfgInitialize(&DmaCentralInst, DMAConfigPtr, DMAConfigPtr->BaseAddress); if (Status != XST_SUCCESS){ xil_printf("... ... DMA CfgInitialize failed!\n"); return; } //Disable Interrupts XDmaCentral_InterruptEnableSet(&DmaCentralInst, 0); if(DEBUG_LVL > 1) xil_printf("... ... complete!\n"); /************************************************************/ /*******************Ethernet**********************************/ if(DEBUG_LVL > 1) xil_printf("... initializing Ethernet\n"); MacCfgPtr = XLlTemac_LookupConfig(TEMAC_DEVICE_ID); Status = XLlTemac_CfgInitialize(&TemacInstance, MacCfgPtr, MacCfgPtr->BaseAddress); XLlFifo_Initialize(&FifoInstance, XLlTemac_LlDevBaseAddress(&TemacInstance)); if (Status != XST_SUCCESS) xil_printf("... ... EMAC init error\n"); if (!XLlTemac_IsFifo(&TemacInstance)) xil_printf("... ... EMAC hw config incorrect\n"); Status = XLlTemac_ClearOptions(&TemacInstance, XTE_LENTYPE_ERR_OPTION | XTE_FLOW_CONTROL_OPTION | XTE_FCS_STRIP_OPTION);// | XTE_MULTICAST_OPTION); Status |= XLlTemac_SetOptions(&TemacInstance, XTE_PROMISC_OPTION | XTE_MULTICAST_OPTION | XTE_BROADCAST_OPTION | XTE_RECEIVER_ENABLE_OPTION | XTE_TRANSMITTER_ENABLE_OPTION); //| XTE_JUMBO_OPTION if (Status != XST_SUCCESS) xil_printf("... ... Error setting EMAC options\n, code %d", Status); // Make sure the TEMAC is ready Status = XLlTemac_ReadReg(TemacInstance.Config.BaseAddress, XTE_RDY_OFFSET); while ((Status & XTE_RDY_HARD_ACS_RDY_MASK) == 0) { Status = XLlTemac_ReadReg(TemacInstance.Config.BaseAddress, XTE_RDY_OFFSET); } XLlTemac_SetOperatingSpeed(&TemacInstance, ENET_LINK_SPEED); usleep(1 * 10000); XLlTemac_Start(&TemacInstance); if(DEBUG_LVL > 1) xil_printf("... ... complete!\n"); /************************************************************/ // Initialize the MAC OPB base address (MAC driver in net/mac.c) xilnet_mac_init((void *)&FifoInstance,(void *)&DmaCentralInst); if(DEBUG_LVL > 1) xil_printf("... complete!\n"); // Print IP address if(DEBUG_LVL > 0) xil_printf("IP Address: %d.%d.%d.%d \n", mb_ip_addr[0], mb_ip_addr[1],mb_ip_addr[2],mb_ip_addr[3]); } void init_socket() { sock = xilsock_socket(AF_INET, SOCK_DGRAM, 0); // Create UDP socket with domain Internet and UDP connection. if (sock == -1) { if(DEBUG_LVL > 0) xil_printf("Error in creating socket\n"); exit(-1); } addr.sin_family = AF_INET; addr.sin_port = myPort; addr.sin_addr.s_addr = INADDR_ANY; // Create the input socket with any incoming address. (0x00000000) XStatus bind = xilsock_bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr)); if (bind == -1) { if(DEBUG_LVL > 0) xil_printf("Unable to bind socket\n"); exit(-1); } alen = sizeof(struct sockaddr); if(DEBUG_LVL > 0) xil_printf("Listening on UDP port %d.\n", myPort); } void shut_socket() { xilsock_close(sock); } int waitForSync() { unsigned int n; XTmrCtr *TmrCtrInstancePtr = &TimerCounter; XTmrCtr_Start(TmrCtrInstancePtr, 1); while(XTmrCtr_GetValue(TmrCtrInstancePtr, 1) < (WAITDURATION_SEC*XPAR_XPS_TIMER_0_CLOCK_FREQ_HZ)){ n = xilnet_eth_recv_frame(receiveBuffer, BUFSIZE); if(n==9999) { //xil_printf("Got Sync\n"); numSync++; return 0; } } XTmrCtr_Stop(TmrCtrInstancePtr, 1); int numblinks; for(numblinks=0;numblinks<10;numblinks++){ userio_write_leds_red(USERIO_BASEADDR,0xF); usleep(100000); userio_write_leds_red(USERIO_BASEADDR,0x0); usleep(100000); userio_write_leds_red(USERIO_BASEADDR,0xF); } userio_write_leds_red(USERIO_BASEADDR,0x0); userio_write_leds_green(USERIO_BASEADDR,0x0); xil_printf("NoSync\n"); return 1; } int main() { int bytesReceived; int bytesSend; int command; int packetNo; int status; unsigned int rxArg0; char done = 0; unsigned char sevenSeg1 = 0x1; int agctarget = -14; int agcnoiseEst = -95; unsigned int agc_dco_state; status = w3_node_init(); if(status != 0) { xil_printf("Error in w3_node_init()! Exiting\n"); return -1; } //Initialize the xilnet stack & default sockets init_net(); init_socket(); #ifdef WARPLAB_CONFIG_2RF xil_printf("WARPLab v6.3b 2x2 Started - Waiting for connection from MATLAB\n"); #elif defined WARPLAB_CONFIG_4RF xil_printf("WARPLab v6.3b 4x4 Started - Waiting for connection from MATLAB\n"); #endif userio_write_leds_red(USERIO_BASEADDR,0x5); int numblinks; for(numblinks=0;numblinks<10;numblinks++){ userio_toggle_leds_red(USERIO_BASEADDR,0xF); usleep(100000); } userio_write_leds_red(USERIO_BASEADDR,0x0); userio_write_leds_green(USERIO_BASEADDR,0x0); XLlFifo_Reset(&FifoInstance); while(done == 0) { if(DEBUG_LVL > 3) xil_printf("|"); bytesReceived = xilsock_recvfrom(sock, receiveBuffer, BUFSIZE, (struct sockaddr *)&addr, &alen); // Wait to receive data if (bytesReceived > 0) { // Check for valid packet packetNo = receivePtr32[0]; command = receivePtr32[1]; rxArg0 = receivePtr32[2]; //Rotate the single active bit sevenSeg1 = ( ((sevenSeg1<<1)&0x7E) | ((sevenSeg1>>5)&0x7E) ); userio_write_hexdisp_right(USERIO_BASEADDR, sevenSeg1<<1); if(DEBUG_LVL > 2) xil_printf("=============\nPacket Received\n Length: %d\n Packet No.: %d\n Command No: %d\n", bytesReceived, packetNo, command); switch(command) { // Decode on incoming command case INITIALIZE: //if(DEBUG_LVL > 1) xil_printf("Initializing Node..."); warplab_buffers_WriteReg_TxDelay(0); warplab_buffers_WriteReg_StartCapture(0); warplab_buffers_WriteReg_TxLength((unsigned int)16383); warplab_buffers_WriteReg_TransMode(0); warplab_buffers_WriteReg_RADIO1TXBUFF_TXEN(0); warplab_buffers_WriteReg_RADIO2TXBUFF_TXEN(0); warplab_buffers_WriteReg_RADIO1RXBUFF_RXEN(0); warplab_buffers_WriteReg_RADIO2RXBUFF_RXEN(0); warplab_AGC_WriteReg_RADIO1_AGC_EN(0); // No radio on slot 1 warplab_AGC_WriteReg_RADIO2_AGC_EN(0); warplab_AGC_WriteReg_RADIO3_AGC_EN(0); warplab_AGC_WriteReg_RADIO4_AGC_EN(0); // No radio on slot 4 warplab_AGC_WriteReg_AGC_TRIGGER_DELAY((unsigned int)50); warplab_buffers_WriteReg_MGC_AGC_SEL(0);// Select MGC by default warplab_AGC_WriteReg_AGC_EN(0); MGC_AGC_Sel_Variable = 0; #ifdef WARPLAB_CONFIG_4RF warplab_buffers_WriteReg_RADIO3TXBUFF_TXEN(0); warplab_buffers_WriteReg_RADIO4TXBUFF_TXEN(0); warplab_buffers_WriteReg_RADIO3RXBUFF_RXEN(0); warplab_buffers_WriteReg_RADIO4RXBUFF_RXEN(0); #endif sendACK(packetNo, command); break; case NETWORKCHECK: sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = numSync; xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); numSync = 0; waitForSync(); break; case BOARDINFO: sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = w3_eeprom_readSerialNum(EEPROM_BASEADDR); sendPtr32[4] = userio_read_fpga_dna_msb(USERIO_BASEADDR); sendPtr32[5] = userio_read_fpga_dna_lsb(USERIO_BASEADDR); sendPtr32[6] = (hw_generation<<24)|(numRadios<<16)|(WARPLAB_MAJOR_VER<<8)|(WARPLAB_MINOR_VER); xilsock_sendto(sock, sendBuffer, 28, (struct sockaddr *)&addr, alen); break; case TX_DELAY: ReadWrite = (unsigned int)receivePtr32[2]; if(0 == ReadWrite) { sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = warplab_mimo_ReadReg_TxDelay(WARPLAB_BASEADDR); if(DEBUG_LVL > 2) xil_printf("Read capt offset of %d\n", (unsigned int)receivePtr32[3]); xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); } if(1 == ReadWrite) { //If the user requests a TX_DELAY that's too big, write the maximum instead warplab_buffers_WriteReg_TxDelay((unsigned int)receivePtr32[3] > 16383 ? 16383 : (unsigned int)receivePtr32[3]); if(DEBUG_LVL > 2) xil_printf("Set capt offset to %d\n", (unsigned int)receivePtr32[3]); sendACK(packetNo, command); } break; case TX_LENGTH: ReadWrite = (unsigned int)receivePtr32[2]; if(0 == ReadWrite) { sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = warplab_mimo_ReadReg_TxLength(WARPLAB_BASEADDR); if(DEBUG_LVL > 2) xil_printf("Read TxLength of %d\n", (unsigned int)receivePtr32[3]); xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); } if(1 == ReadWrite) { //If the user requests a TX_LENGTH that's too big, write the maximum instead warplab_buffers_WriteReg_TxLength((unsigned int)receivePtr32[3] > 16383 ? 16383 : (unsigned int)receivePtr32[3]); if(DEBUG_LVL > 2) xil_printf("Set TxLength to %d\n", (unsigned int)receivePtr32[3]); sendACK(packetNo, command); } break; case TX_MODE: ReadWrite = (unsigned int)receivePtr32[2]; if(0 == ReadWrite) { sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = warplab_mimo_ReadReg_TransMode(WARPLAB_BASEADDR); xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); } if(1 == ReadWrite) { warplab_buffers_WriteReg_TransMode((unsigned int)receivePtr32[3]); sendACK(packetNo, command); } break; case RX1BUFFERS_DEBUG: break; case RX2BUFFERS_DEBUG: break; #ifdef WARPLAB_CONFIG_4RF case RX3BUFFERS_DEBUG: break; case RX4BUFFERS_DEBUG: break; #endif case MGC_AGC_SEL: //ReadWrite = (unsigned int)receivePtr32[2]; MGC_AGC_Sel_Variable = (unsigned int)receivePtr32[2]; //if(0 == ReadWrite) //{ // sendPtr32[0] = packetNo + 1; // sendPtr32[1] = ACK; // sendPtr32[2] = command; // sendPtr32[3] = warplab_mimo_4x4_ReadReg_MGC_AGC_SEL(XPAR_WARPLAB_MIMO_4X4_OPBW_0_BASEADDR); // xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); //} //if(1 == ReadWrite) //{ warplab_buffers_WriteReg_MGC_AGC_SEL(MGC_AGC_Sel_Variable); if(0 == MGC_AGC_Sel_Variable) { warplab_AGC_WriteReg_AGC_EN(0); radio_controller_setCtrlSource(RC_BASEADDR, (RC_RFA | RC_RFB), RC_REG0_RXHP_CTRLSRC, RC_CTRLSRC_REG); radio_controller_setRxGainSource(RC_BASEADDR, (RC_RFA | RC_RFB), RC_GAINSRC_SPI); } if(1 == MGC_AGC_Sel_Variable) { radio_controller_setCtrlSource(RC_BASEADDR, (RC_RFA | RC_RFB), RC_REG0_RXHP_CTRLSRC, RC_CTRLSRC_HW); radio_controller_setRxGainSource(RC_BASEADDR, (RC_RFA | RC_RFB), RC_GAINSRC_HW); // Initialize the AGC warplab_AGC_Initialize(agcnoiseEst); warplab_AGC_setNoiseEstimate(agcnoiseEst); // ofdm_AGC_FiltSel(0); No decimation option in WARPLab AGC warplab_AGC_SetDCO(0); warplab_AGC_SetTarget(agctarget); warplab_AGC_Reset(); } sendACK(packetNo, command); //} break; case CARRIER_CHANNEL: Radios_WirelessChan = ((unsigned int)receivePtr32[2]); //Channels in [1...37] are valid // Values in [1...14] select 2.4GHz channels [1...14] // Values in [15...37] select a 5GHz channels [1...23] if(Radios_WirelessChan <= (14+23)) { if(Radios_WirelessChan <= 14) { radio_controller_setCenterFrequency(RC_BASEADDR, (RC_RFA|RC_RFB), RC_24GHZ, Radios_WirelessChan); } else { radio_controller_setCenterFrequency(RC_BASEADDR, (RC_RFA|RC_RFB), RC_5GHZ, (Radios_WirelessChan-14)); } } sendACK(packetNo, command); break; case TX_LPF_CORN_FREQ: Radios_Tx_LPF_Corn_Freq = ((unsigned int)receivePtr32[2]); radio_controller_setRadioParam(RC_BASEADDR, (RC_RFA|RC_RFB), RC_PARAMID_TXLPF_BW, Radios_Tx_LPF_Corn_Freq&0x3); sendACK(packetNo, command); break; case RX_LPF_CORN_FREQ: Radios_Rx_LPF_Corn_Freq = ((unsigned int)receivePtr32[2]); radio_controller_setRadioParam(RC_BASEADDR, (RC_RFA|RC_RFB), RC_PARAMID_RXLPF_BW, Radios_Rx_LPF_Corn_Freq&0x3); sendACK(packetNo, command); break; case RADIO1_TXGAINS: //Extract the radio gain config options from the received Ethernet packet Radio1_TxGain_BB = (((unsigned int)receivePtr32[2])>>16)&0x3; Radio1_TxGain_RF = ((unsigned int)receivePtr32[2])&0x3F; radio_controller_setRadioParam(RC_BASEADDR, RC_RFA, RC_PARAMID_TXGAIN_BB, Radio1_TxGain_BB); radio_controller_setRadioParam(RC_BASEADDR, RC_RFA, RC_PARAMID_TXGAIN_RF, Radio1_TxGain_RF); //radio_controller_setTxGainTarget(RC_BASEADDR, RC_RFA, Radio1_TxGain_RF); sendACK(packetNo, command); break; case RADIO1_RXGAINS: //Extract the radio gain config options from the received Ethernet packet Radio1_RxGain_RF = (((unsigned int)receivePtr32[2])>>16)&0x3; Radio1_RxGain_BB = ((unsigned int)receivePtr32[2])&0x3F; radio_controller_setRadioParam(RC_BASEADDR, RC_RFA, RC_PARAMID_RXGAIN_BB, Radio1_RxGain_BB); radio_controller_setRadioParam(RC_BASEADDR, RC_RFA, RC_PARAMID_RXGAIN_RF, Radio1_RxGain_RF); sendACK(packetNo, command); break; case RADIO2_TXGAINS: //Extract the radio gain config options from the received Ethernet packet Radio2_TxGain_BB = (((unsigned int)receivePtr32[2])>>16)&0x3; Radio2_TxGain_RF = ((unsigned int)receivePtr32[2])&0x3F; radio_controller_setRadioParam(RC_BASEADDR, RC_RFB, RC_PARAMID_TXGAIN_BB, Radio2_TxGain_BB); radio_controller_setRadioParam(RC_BASEADDR, RC_RFB, RC_PARAMID_TXGAIN_RF, Radio2_TxGain_RF); sendACK(packetNo, command); break; case RADIO2_RXGAINS: //Extract the radio gain config options from the received Ethernet packet Radio2_RxGain_RF = (((unsigned int)receivePtr32[2])>>16)&0x3; Radio2_RxGain_BB = ((unsigned int)receivePtr32[2])&0x3F; radio_controller_setRadioParam(RC_BASEADDR, RC_RFB, RC_PARAMID_RXGAIN_BB, Radio2_RxGain_BB); radio_controller_setRadioParam(RC_BASEADDR, RC_RFB, RC_PARAMID_RXGAIN_RF, Radio2_RxGain_RF); sendACK(packetNo, command); break; #ifdef WARPLAB_CONFIG_4RF case RADIO3_TXGAINS: sendACK(packetNo, command); break; case RADIO3_RXGAINS: sendACK(packetNo, command); break; case RADIO4_TXGAINS: sendACK(packetNo, command); break; case RADIO4_RXGAINS: sendACK(packetNo, command); break; #endif case RADIO1_TXEN: radio_controller_TxEnable(RC_BASEADDR, (RC_RFA)); if(DEBUG_LVL > 1) xil_printf("Radio 1 Tx Enabled\n"); sendACK(packetNo, command); break; case RADIO2_TXEN: radio_controller_TxEnable(RC_BASEADDR, (RC_RFB)); if(DEBUG_LVL > 1) xil_printf("Radio 2 Tx Enabled\n"); sendACK(packetNo, command); break; #ifdef WARPLAB_CONFIG_4RF case RADIO3_TXEN: sendACK(packetNo, command); break; case RADIO4_TXEN: sendACK(packetNo, command); break; #endif case RADIO1_TXDIS: radio_controller_TxRxDisable(RC_BASEADDR, (RC_RFA)); if(DEBUG_LVL > 1) xil_printf("Radio 1 Tx Disabled\n"); sendACK(packetNo, command); break; case RADIO2_TXDIS: radio_controller_TxRxDisable(RC_BASEADDR, (RC_RFB)); if(DEBUG_LVL > 1) xil_printf("Radio 2 Tx Disabled\n"); sendACK(packetNo, command); break; #ifdef WARPLAB_CONFIG_4RF case RADIO3_TXDIS: sendACK(packetNo, command); break; case RADIO4_TXDIS: sendACK(packetNo, command); break; #endif case RADIO1_RXEN: /***************** Setup the radio board ************/ if(0 == MGC_AGC_Sel_Variable) { // Disable the Rx HP filter // Only needed in Manual Gain Control (MGC) Mode // In Automatic Gain Control (AGC) Mode, the RxHp // is controlled by the AGC core radio_controller_setRxHP(RC_BASEADDR, (RC_RFA), RC_RXHP_OFF); } // usleep(10); //Enable the receiver radio_controller_RxEnable(RC_BASEADDR, (RC_RFA)); if(1 == MGC_AGC_Sel_Variable) { //Enable this radio's AGC if user has set AGC Mode warplab_AGC_WriteReg_RADIO1_AGC_EN(1); } /***************** END Setup the radio board ************/ //if(DEBUG_LVL > 1) xil_printf("Radio 1 Rx Enabled\n"); if(DEBUG_LVL > 1) xil_printf("Radio 1 Rx Enabled\n"); sendACK(packetNo, command); break; case RADIO2_RXEN: /***************** Setup the radio board ************/ if(0 == MGC_AGC_Sel_Variable) { // Disable the Rx HP filter // Only needed in Manual Gain Control (MGC) Mode // In Automatic Gain Control (AGC) Mode, the RxHp // is controlled by the AGC core //WarpRadio_v1_RxHpDisable(radio2); radio_controller_setRxHP(RC_BASEADDR, (RC_RFB), RC_RXHP_OFF); } // usleep(10); //Enable the receiver radio_controller_RxEnable(RC_BASEADDR, (RC_RFB)); if(1 == MGC_AGC_Sel_Variable) { //Enable this radio's AGC if user has set AGC Mode warplab_AGC_WriteReg_RADIO2_AGC_EN(1); } /***************** END Setup the radio board ************/ //if(DEBUG_LVL > 1) xil_printf("Radio 2 Rx Enabled\n"); if(DEBUG_LVL > 1) xil_printf("Radio 2 Rx Enabled\n"); sendACK(packetNo, command); break; #ifdef WARPLAB_CONFIG_4RF case RADIO3_RXEN: sendACK(packetNo, command); break; case RADIO4_RXEN: sendACK(packetNo, command); break; #endif case RADIO1_RXDIS: radio_controller_TxRxDisable(RC_BASEADDR, (RC_RFA)); if(0 == MGC_AGC_Sel_Variable) { //Enable the Rx HP filter // Only needed in Manual Gain Control (MGC) Mode // In Automatic Gain Control (AGC) Mode, the RxHp // is controlled by the AGC core radio_controller_setRxHP(RC_BASEADDR, (RC_RFA), RC_RXHP_ON); } if(1 == MGC_AGC_Sel_Variable) { //Disable this radio's AGC if user has set AGC Mode warplab_AGC_WriteReg_RADIO1_AGC_EN(0); } //if(DEBUG_LVL > 1) xil_printf("Radio 1 Rx Disabled\n"); if(DEBUG_LVL > 1) xil_printf("Radio 1 Rx Disabled\n"); sendACK(packetNo, command); break; case RADIO2_RXDIS: radio_controller_TxRxDisable(RC_BASEADDR, (RC_RFB)); if(0 == MGC_AGC_Sel_Variable) { //Enable the Rx HP filter // Only needed in Manual Gain Control (MGC) Mode // In Automatic Gain Control (AGC) Mode, the RxHp // is controlled by the AGC core radio_controller_setRxHP(RC_BASEADDR, (RC_RFB), RC_RXHP_ON); } if(1 == MGC_AGC_Sel_Variable) { //Disable this radio's AGC if user has set AGC Mode warplab_AGC_WriteReg_RADIO2_AGC_EN(0); } //if(DEBUG_LVL > 1) xil_printf("Radio 2 Rx Disabled\n"); if(DEBUG_LVL > 1) xil_printf("Radio 2 Rx Disabled\n"); sendACK(packetNo, command); break; #ifdef WARPLAB_CONFIG_4RF case RADIO3_RXDIS: WarpRadio_v1_TxRxDisable(radio3); if(0 == MGC_AGC_Sel_Variable) { //Enable the Rx HP filter // Only needed in Manual Gain Control (MGC) Mode // In Automatic Gain Control (AGC) Mode, the RxHp // is controlled by the AGC core WarpRadio_v1_RxHpEnable(radio3); } if(1 == MGC_AGC_Sel_Variable) { //Disable this radio's AGC if user has set AGC Mode warplab_AGC_WriteReg_RADIO3_AGC_EN(0); } //if(DEBUG_LVL > 1) xil_printf("Radio 3 Rx Disabled\n"); if(DEBUG_LVL > 1) xil_printf("Radio 3 Rx Disabled\n"); sendACK(packetNo, command); break; case RADIO4_RXDIS: WarpRadio_v1_TxRxDisable(radio4); if(0 == MGC_AGC_Sel_Variable) { //Enable the Rx HP filter // Only needed in Manual Gain Control (MGC) Mode // In Automatic Gain Control (AGC) Mode, the RxHp // is controlled by the AGC core WarpRadio_v1_RxHpEnable(radio4); } if(1 == MGC_AGC_Sel_Variable) { //Disable this radio's AGC if user has set AGC Mode warplab_AGC_WriteReg_RADIO4_AGC_EN(0); } //if(DEBUG_LVL > 1) xil_printf("Radio 4 Rx Disabled\n"); if(DEBUG_LVL > 1) xil_printf("Radio 4 Rx Disabled\n"); sendACK(packetNo, command); break; #endif case RADIO1_TXDATA: memcpy ( (unsigned int *)(WARPLAB_TXBUFF_RADIO1 + 4*rxArg0),\ (unsigned int *)(receivePtr32 + 3),\ (bytesReceived-12) ); sendACK(packetNo, command); break; case RADIO2_TXDATA: //if(DEBUG_LVL > 1) xil_printf("Got some data for Radio 2 Tx (offset: %x)\n",rxArg0); //if(DEBUG_LVL > 1) xil_printf("Sample bytes: %x %x %x %x\n", *(unsigned int *)(receivePtr32 + 3), *(unsigned int *)(receivePtr32 + 4), *(unsigned int *)(receivePtr32 + 5), *(unsigned int *)(receivePtr32 + 6)); //if(DEBUG_LVL > 1) xil_printf("Got some data for Radio 2 Tx (offset: %x)\n",rxArg0); //if(DEBUG_LVL > 1) xil_printf("Got some data for Radio 2 Tx (offset: %x)\n",rxArg0); memcpy ( (unsigned int *)(WARPLAB_TXBUFF_RADIO2 + 4*rxArg0),\ (unsigned int *)(receivePtr32 + 3),\ (bytesReceived-12) ); sendACK(packetNo, command); break; #ifdef WARPLAB_CONFIG_4RF case RADIO3_TXDATA: //if(DEBUG_LVL > 1) xil_printf("Got some data for Radio 3 Tx (offset: %x)\n",rxArg0); //if(DEBUG_LVL > 1) xil_printf("Sample bytes: %x %x %x %x\n", *(unsigned int *)(receivePtr32 + 3), *(unsigned int *)(receivePtr32 + 4), *(unsigned int *)(receivePtr32 + 5), *(unsigned int *)(receivePtr32 + 6)); //if(DEBUG_LVL > 1) xil_printf("Got some data for Radio 3 Tx (offset: %x)\n",rxArg0); //if(DEBUG_LVL > 1) xil_printf("Got some data for Radio 3 Tx (offset: %x)\n",rxArg0); /* memcpy ( (unsigned int *)(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR + warplab_mimo_2x2_SMWO_TxBuff_Radio3_OFFSET + 4*rxArg0),\ (unsigned int *)(receivePtr32 + 3),\ (bytesReceived-12) ); */ memcpy ( (unsigned int *)(WARPLAB_TXBUFF_RADIO3 + 4*rxArg0),\ (unsigned int *)(receivePtr32 + 3),\ (bytesReceived-12) ); sendACK(packetNo, command); break; case RADIO4_TXDATA: memcpy ( (unsigned int *)(WARPLAB_TXBUFF_RADIO4 + 4*rxArg0),\ (unsigned int *)(receivePtr32 + 3),\ (bytesReceived-12) ); sendACK(packetNo, command); break; #endif case RADIO1_RXDATA: memcpy ( (unsigned int *)(sendPtr32 + 4), \ (unsigned int *)(WARPLAB_RXBUFF_RADIO1 + 4*rxArg0),\ 1024 ); sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = rxArg0; xilsock_sendto(sock, sendBuffer, 16+1024, (struct sockaddr *)&addr, alen); break; case RADIO2_RXDATA: //while(warplab_mimo_2x2_ReadReg_CaptureDone(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR) == 0) {} /* memcpy ( (unsigned int *)(sendPtr32 + 4), \ (unsigned int *)(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR + warplab_mimo_2x2_SMRO_RxBuff_Radio2_OFFSET + 4*rxArg0),\ 1024 ); */ memcpy ( (unsigned int *)(sendPtr32 + 4), \ (unsigned int *)(WARPLAB_RXBUFF_RADIO2 + 4*rxArg0),\ 1024 ); //if(DEBUG_LVL > 1) xil_printf("Read Rx data (offset: %x)\n",rxArg0); //if(DEBUG_LVL > 1) xil_printf("Copied 1024 bytes from %x\n",(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR + warplab_mimo_2x2_SMRO_RxBuff_Radio2_OFFSET + rxArg0)); sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = rxArg0; xilsock_sendto(sock, sendBuffer, 16+1024, (struct sockaddr *)&addr, alen); break; #ifdef WARPLAB_CONFIG_4RF case RADIO3_RXDATA: //while(warplab_mimo_2x2_ReadReg_CaptureDone(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR) == 0) {} /* memcpy ( (unsigned int *)(sendPtr32 + 4), \ (unsigned int *)(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR + warplab_mimo_2x2_SMRO_RxBuff_Radio3_OFFSET + 4*rxArg0),\ 1024 ); */ memcpy ( (unsigned int *)(sendPtr32 + 4), \ (unsigned int *)(WARPLAB_RXBUFF_RADIO3 + 4*rxArg0),\ 1024 ); //if(DEBUG_LVL > 1) xil_printf("Read Rx data (offset: %x)\n",rxArg0); //if(DEBUG_LVL > 1) xil_printf("Copied 1024 bytes from %x\n",(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR + warplab_mimo_2x2_SMRO_RxBuff_Radio3_OFFSET + rxArg0)); sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = rxArg0; xilsock_sendto(sock, sendBuffer, 16+1024, (struct sockaddr *)&addr, alen); break; case RADIO4_RXDATA: memcpy ( (unsigned int *)(sendPtr32 + 4), \ (unsigned int *)(WARPLAB_RXBUFF_RADIO4 + 4*rxArg0),\ 1024 ); sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = rxArg0; xilsock_sendto(sock, sendBuffer, 16+1024, (struct sockaddr *)&addr, alen); break; #endif case RADIO1_RSSIDATA: memcpy ( (unsigned int *)(sendPtr32 + 4), \ (unsigned int *)(WARPLAB_RSSIBUFF_RADIO1 + 4*rxArg0),\ 1024 ); sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = rxArg0; xilsock_sendto(sock, sendBuffer, 16+1024, (struct sockaddr *)&addr, alen); break; case RADIO2_RSSIDATA: //while(warplab_mimo_2x2_ReadReg_CaptureDone(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR) == 0) {} /* memcpy ( (unsigned int *)(sendPtr32 + 4), \ (unsigned int *)(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR + warplab_mimo_2x2_SMRO_RSSIBuff_Radio2_OFFSET + 4*rxArg0),\ 1024 ); */ memcpy ( (unsigned int *)(sendPtr32 + 4), \ (unsigned int *)(WARPLAB_RSSIBUFF_RADIO2 + 4*rxArg0),\ 1024 ); //if(DEBUG_LVL > 1) xil_printf("Read RSSI data (offset: %x)\n",rxArg0); //if(DEBUG_LVL > 1) xil_printf("Copied 1024 bytes from %x\n",(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR + warplab_mimo_2x2_SMRO_RSSIBuff_Radio2_OFFSET + 4*rxArg0)); sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = rxArg0; xilsock_sendto(sock, sendBuffer, 16+1024, (struct sockaddr *)&addr, alen); break; #ifdef WARPLAB_CONFIG_4RF case RADIO3_RSSIDATA: //while(warplab_mimo_2x2_ReadReg_CaptureDone(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR) == 0) {} /* memcpy ( (unsigned int *)(sendPtr32 + 4), \ (unsigned int *)(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR + warplab_mimo_2x2_SMRO_RSSIBuff_Radio3_OFFSET + 4*rxArg0),\ 1024 ); */ memcpy ( (unsigned int *)(sendPtr32 + 4), \ (unsigned int *)(WARPLAB_RSSIBUFF_RADIO3 + 4*rxArg0),\ 1024 ); //if(DEBUG_LVL > 1) xil_printf("Read RSSI data (offset: %x)\n",rxArg0); //if(DEBUG_LVL > 1) xil_printf("Copied 1024 bytes from %x\n",(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR + warplab_mimo_2x2_SMRO_RSSIBuff_Radio3_OFFSET + 4*rxArg0)); sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = rxArg0; xilsock_sendto(sock, sendBuffer, 16+1024, (struct sockaddr *)&addr, alen); break; case RADIO4_RSSIDATA: memcpy ( (unsigned int *)(sendPtr32 + 4), \ (unsigned int *)(WARPLAB_RSSIBUFF_RADIO4 + 4*rxArg0),\ 1024 ); sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = rxArg0; xilsock_sendto(sock, sendBuffer, 16+1024, (struct sockaddr *)&addr, alen); break; #endif case RADIO1TXBUFF_TXEN: warplab_buffers_WriteReg_RADIO1TXBUFF_TXEN(1); sendACK(packetNo, command); break; case RADIO2TXBUFF_TXEN: warplab_buffers_WriteReg_RADIO2TXBUFF_TXEN(1); sendACK(packetNo, command); break; #ifdef WARPLAB_CONFIG_4RF case RADIO3TXBUFF_TXEN: warplab_buffers_WriteReg_RADIO3TXBUFF_TXEN(1); sendACK(packetNo, command); break; case RADIO4TXBUFF_TXEN: warplab_buffers_WriteReg_RADIO4TXBUFF_TXEN(1); sendACK(packetNo, command); break; #endif case RADIO1TXBUFF_TXDIS: warplab_buffers_WriteReg_RADIO1TXBUFF_TXEN(0); sendACK(packetNo, command); break; case RADIO2TXBUFF_TXDIS: warplab_buffers_WriteReg_RADIO2TXBUFF_TXEN(0); sendACK(packetNo, command); break; #ifdef WARPLAB_CONFIG_4RF case RADIO3TXBUFF_TXDIS: warplab_buffers_WriteReg_RADIO3TXBUFF_TXEN(0); sendACK(packetNo, command); break; case RADIO4TXBUFF_TXDIS: warplab_buffers_WriteReg_RADIO4TXBUFF_TXEN(0); sendACK(packetNo, command); break; #endif case RADIO1RXBUFF_RXEN: warplab_buffers_WriteReg_RADIO1RXBUFF_RXEN(1); sendACK(packetNo, command); break; case RADIO2RXBUFF_RXEN: warplab_buffers_WriteReg_RADIO2RXBUFF_RXEN(1); sendACK(packetNo, command); break; #ifdef WARPLAB_CONFIG_4RF case RADIO3RXBUFF_RXEN: warplab_buffers_WriteReg_RADIO3RXBUFF_RXEN(1); sendACK(packetNo, command); break; case RADIO4RXBUFF_RXEN: warplab_buffers_WriteReg_RADIO4RXBUFF_RXEN(1); sendACK(packetNo, command); break; #endif case RADIO1RXBUFF_RXDIS: warplab_buffers_WriteReg_RADIO1RXBUFF_RXEN(0); sendACK(packetNo, command); break; case RADIO2RXBUFF_RXDIS: warplab_buffers_WriteReg_RADIO2RXBUFF_RXEN(0); sendACK(packetNo, command); break; #ifdef WARPLAB_CONFIG_4RF case RADIO3RXBUFF_RXDIS: warplab_buffers_WriteReg_RADIO3RXBUFF_RXEN(0); sendACK(packetNo, command); break; case RADIO4RXBUFF_RXDIS: warplab_buffers_WriteReg_RADIO4RXBUFF_RXEN(0); sendACK(packetNo, command); break; #endif case RX_DONECHECK: sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; if(warplab_mimo_ReadReg_CaptureDone(WARPLAB_BASEADDR) == 0) sendPtr32[3] = 0; else sendPtr32[3] = 1; xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); break; case RX_DONEREADING: //warplab_mimo_2x2_WriteReg_DoneReading(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR, 1); //warplab_mimo_2x2_WriteReg_DoneReading(XPAR_WARPLAB_MIMO_2X2_OPBW_0_BASEADDR, 0); sendACK(packetNo, command); break; case RX_START: //if(DEBUG_LVL > 1) xil_printf("Starting Rx\n"); //if(DEBUG_LVL > 1) xil_printf("Starting Rx\n"); sendACK(packetNo, command); if(waitForSync() == 0) { warplab_buffers_WriteReg_StartCapture(1); warplab_AGC_Start(); warplab_buffers_WriteReg_StartCapture(0); //if(DEBUG_LVL > 1) xil_printf("Capture started\n"); } else if(DEBUG_LVL > 1) xil_printf("No MAGIC_SYNC received; canceling Rx Capture\n"); break; case TX_START: //if(DEBUG_LVL > 1) xil_printf("Starting Tx\n"); if(DEBUG_LVL > 1) xil_printf("Starting Tx\n"); sendACK(packetNo, command); if(waitForSync() == 0) { warplab_buffers_WriteReg_StartTx(1); warplab_buffers_WriteReg_StartTx(0); //if(DEBUG_LVL > 1) xil_printf("Transmit started\n"); } else if(DEBUG_LVL > 1) xil_printf("No MAGIC_SYNC received; canceling Tx\n"); break; case TX_STOP: sendACK(packetNo, command); warplab_buffers_WriteReg_StopTx(1); warplab_buffers_WriteReg_StopTx(0); break; case TXRX_START: if(DEBUG_LVL > 1) xil_printf("Starting TxRX\n"); sendACK(packetNo, command); if(waitForSync() == 0) { warplab_buffers_WriteReg_StartTxRx(1); warplab_buffers_WriteReg_StartTxRx(0); } else if(DEBUG_LVL > 1) xil_printf("No MAGIC_SYNC received; canceling TxRx\n"); break; case READ_AGC_DONE_ADDR: sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = warplab_mimo_ReadReg_AGCDoneAddr(WARPLAB_BASEADDR); xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); break; case READ_RADIO1AGCDONERSSI: sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = warplab_mimo_ReadReg_Radio1AGCDoneRSSI(WARPLAB_BASEADDR); xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); break; case READ_RADIO2AGCDONERSSI: sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = warplab_mimo_ReadReg_Radio2AGCDoneRSSI(WARPLAB_BASEADDR); xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); break; #ifdef WARPLAB_CONFIG_4RF case READ_RADIO3AGCDONERSSI: sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = warplab_mimo_ReadReg_Radio3AGCDoneRSSI(WARPLAB_BASEADDR); xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); break; case READ_RADIO4AGCDONERSSI: sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = warplab_mimo_ReadReg_Radio4AGCDoneRSSI(WARPLAB_BASEADDR); xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); break; #endif case AGC_RESET: warplab_AGC_Reset(); sendACK(packetNo, command); break; case READ_AGC_GAINS: sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = warplab_AGC_GetGains(); xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); break; case SET_AGC_TARGET_dBm: agctarget = (int)receivePtr32[2]; warplab_AGC_SetTarget(agctarget); //xil_printf("agctarget = %d\n",agctarget); sendACK(packetNo, command); break; case SET_AGC_DCO_EN_DIS: agc_dco_state = (unsigned int)receivePtr32[2]; warplab_AGC_SetDCO(agc_dco_state); warplab_buffers_WriteReg_DCO_EN_SEL(agc_dco_state); //xil_printf("agc_dco_state = %d\n",agc_dco_state); sendACK(packetNo, command); break; case SET_AGC_NOISEEST_dBm: agcnoiseEst = (int)receivePtr32[2]; warplab_AGC_setNoiseEstimate(agcnoiseEst); //xil_printf("agctarget = %d\n",agctarget); sendACK(packetNo, command); break; case SET_AGC_THRESHOLDS: warplab_AGC_WriteReg_Thresholds((unsigned int)receivePtr32[2]); sendACK(packetNo, command); break; case SET_AGC_TRIG_DELAY: warplab_AGC_WriteReg_AGC_TRIGGER_DELAY((unsigned int)receivePtr32[2]); sendACK(packetNo, command); break; case READ_AGC_THRESHOLDS: sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = command; sendPtr32[3] = warplab_AGC_ReadReg_Thresholds(XPAR_WARPLAB_MIMO_4X4_AGC_PLBW_0_BASEADDR); xilsock_sendto(sock, sendBuffer, 16, (struct sockaddr *)&addr, alen); break; case CLOSE: if(DEBUG_LVL > 1) xil_printf("Closing sockets.\n"); sendACK(packetNo, command); done = 1; break; case TX_TEST: if(DEBUG_LVL > 1) xil_printf("Starting Tx Test\n"); sendACK(packetNo, command); break; default: if(DEBUG_LVL > 1) xil_printf("Received command (%d) is not recognized. Please retry transmission.\n", command); sendPtr32[0] = packetNo + 1; sendPtr32[1] = NOACK; bytesSend = 8; xilsock_sendto(sock, sendBuffer, bytesSend, (struct sockaddr *)&addr, alen); } } } shut_socket(); return 0; } void sendACK(unsigned int packetNo, unsigned int commandToACK) { sendPtr32[0] = packetNo + 1; sendPtr32[1] = ACK; sendPtr32[2] = commandToACK; xilsock_sendto(sock, sendBuffer, 12, (struct sockaddr *)&addr, alen); return; } unsigned char sevenSegmentMap(unsigned char x) { switch(x) { case(0x0) : return 0x007E; case(0x1) : return 0x0030; case(0x2) : return 0x006D; case(0x3) : return 0x0079; case(0x4) : return 0x0033; case(0x5) : return 0x005B; case(0x6) : return 0x005F; case(0x7) : return 0x0070; case(0x8) : return 0x007F; case(0x9) : return 0x007B; case(0xA) : return 0x0077; case(0xB) : return 0x007F; case(0xC) : return 0x004E; case(0xD) : return 0x007E; case(0xE) : return 0x004F; case(0xF) : return 0x0047; default : return 0x0000; } } #define XPAR_EEPROM_CONTROLLER_BASEADDR XPAR_EEPROM_CONTROLLER_MEM0_BASEADDR //New TxDCO calibration code int warpphy_applyTxDCOCalibration(unsigned int radioSelection) { #if 0 int eepromStatus = 0; short calReadback = 0; signed short best_I, best_Q; unsigned char radioNum; Xuint8 memory[8], version, revision, valid, i; Xuint16 serial; //Radio selection will be 0x11111111, 0x22222222, 0x44444444 or 0x88888888 // corresponding to radios in slots 1, 2, 3 or 4 // We need the slot number to initialize the EEPROM radioNum = (radioSelection & 0xF) == 1 ? 1 : ( (radioSelection & 0xF) == 2 ? 2 : ( (radioSelection & 0xF) == 4 ? 3 : 4 ) ); if(DEBUG_LVL>2) xil_printf("Applying TxDCO correction for radio %d\n", radioNum); //Mimic the radio test code, in hopes of a more stable EEPROM read... //Choose the EEPROM on the selected radio board; second arg is [0,1,2,3,4] for [FPGA, radio1, radio2, radio3, radio4] eepromStatus = WarpEEPROM_EEPROMSelect((unsigned int *)XPAR_EEPROM_CONTROLLER_BASEADDR, 0); if(eepromStatus != 0) { if(DEBUG_LVL>2) xil_printf("EEPROM Select Failed!\n"); return -1; } //Initialize the EEPROM controller eepromStatus = WarpEEPROM_Initialize((unsigned int *)XPAR_EEPROM_CONTROLLER_BASEADDR); if(eepromStatus != 0) { if(DEBUG_LVL>2) xil_printf("EEPROM Init Returned %x\n", eepromStatus); if(DEBUG_LVL>2) xil_printf("EEPROM Init Failed!\n"); return -1; } //Select the EEPROM on the current radio board eepromStatus = WarpEEPROM_EEPROMSelect((unsigned int*)XPAR_EEPROM_CONTROLLER_BASEADDR, radioNum); if(eepromStatus != 0) { if(DEBUG_LVL>2) xil_printf("TxDCO: EEPROM error\n"); return -1; } //Read the first page from the EERPOM WarpEEPROM_ReadMem((unsigned int*)XPAR_EEPROM_CONTROLLER_BASEADDR, 0, 0, memory); version = (memory[0] & 0xE0) >> 5; revision = (memory[1] & 0xE0) >> 5; valid = memory[1] & 0x1F; if(DEBUG_LVL>2) xil_printf("\n\nEEPROM Values for Radio Board in Slot %d\n", radioNum); if(DEBUG_LVL>2) xil_printf(" WARP Radio Board Version %d.%d\n", version, revision); serial = WarpEEPROM_ReadWARPSerial((unsigned int*)XPAR_EEPROM_CONTROLLER_BASEADDR); if(DEBUG_LVL>2) xil_printf(" Serial Number (WARP): WR-a-%05d\n", serial); WarpEEPROM_ReadDSSerial((unsigned int*)XPAR_EEPROM_CONTROLLER_BASEADDR, memory); if(DEBUG_LVL>2) print(" EEPROM Hard-wired Serial Number: "); if(DEBUG_LVL>2){ for(i=1;i<7;i++) xil_printf(" %x",memory[7-i]); xil_printf("\n\n"); } //Read the Tx DCO values calReadback = WarpEEPROM_ReadRadioCal((unsigned int*)XPAR_EEPROM_CONTROLLER_BASEADDR, 2, 1); //Scale the stored values best_I = (signed short)(((signed char)(calReadback & 0xFF))<<1); best_Q = (signed short)(((signed char)((calReadback>>8) & 0xFF))<<1); if(DEBUG_LVL>2) xil_printf("TxDCO: Applied values to radio %d - I: %d\tQ: %d\n", radioNum, best_I, best_Q); //Finally, write the Tx DCO values to the DAC WarpRadio_v1_DACOffsetAdj(ICHAN, best_I, radioSelection); WarpRadio_v1_DACOffsetAdj(QCHAN, best_Q, radioSelection); #endif return 0; } void warplab_AGC_Reset() { // Cycle the agc's software reset port warplab_AGC_WriteReg_SRESET_IN(1); usleep(10); warplab_AGC_WriteReg_SRESET_IN(0); usleep(100); return; } void warplab_AGC_MasterReset() { // Cycle the master reset register in the AGC and enable it warplab_AGC_WriteReg_AGC_EN(0); usleep(10); warplab_AGC_WriteReg_MRESET_IN(0); usleep(10); warplab_AGC_WriteReg_MRESET_IN(1); usleep(10); warplab_AGC_WriteReg_MRESET_IN(0); usleep(10); warplab_AGC_WriteReg_AGC_EN(1); return; } void warplab_AGC_Start() { // Cycle the agc's packet in port warplab_AGC_WriteReg_PACKET_IN(1); usleep(10); warplab_AGC_WriteReg_PACKET_IN(0); usleep(100); return; } void warplab_AGC_Initialize(int noise_estimate) { int g_bbset = 0; // First set all standard parameters // Turn off both resets and the master enable warplab_AGC_WriteReg_AGC_EN(0); warplab_AGC_WriteReg_SRESET_IN(0); warplab_AGC_WriteReg_MRESET_IN(0); // An adjustment parameter warplab_AGC_WriteReg_ADJ(8); // Timing for the DC-offset correction warplab_AGC_WriteReg_DCO_Timing(0x12001000); // Initial baseband gain setting warplab_AGC_WriteReg_GBB_init(52); // RF gain AGCstate thresholds warplab_AGC_WriteReg_Thresholds(0xD5CBA6); // Overall AGC timing warplab_AGC_WriteReg_Timing(0x9A962A28);//0x826E3C0A; // vIQ and RSSI average lengths warplab_AGC_WriteReg_AVG_LEN(0x10F); //103 // Disable DCO, disable DCO subtraction warplab_AGC_WriteReg_Bits(0x0); // Compute and set the initial g_BB gain value from the noise estimate // The initial g_bb sets noise to -19 db, assuming 32 db RF gain g_bbset = -19 - 32 - noise_estimate; warplab_AGC_WriteReg_GBB_init(g_bbset); // Perform a master reset warplab_AGC_MasterReset(); // Agc is now reset and enabled, ready to go! return; } void warplab_AGC_setNoiseEstimate(int noise_estimate) { int g_bbset; g_bbset = -19 - 32 - noise_estimate; warplab_AGC_WriteReg_GBB_init(g_bbset); return; } unsigned int warplab_AGC_GetGains(void) { unsigned int gBB_A, gRF_A, gBB_B, gRF_B, gBB_C, gRF_C, gBB_D, gRF_D, gains; // Get the gains from the registers gBB_A = warplab_AGC_ReadReg_GBB_A(XPAR_WARPLAB_MIMO_4X4_AGC_PLBW_0_BASEADDR); gRF_A = warplab_AGC_ReadReg_GRF_A(XPAR_WARPLAB_MIMO_4X4_AGC_PLBW_0_BASEADDR); gBB_B = warplab_AGC_ReadReg_GBB_B(XPAR_WARPLAB_MIMO_4X4_AGC_PLBW_0_BASEADDR); gRF_B = warplab_AGC_ReadReg_GRF_B(XPAR_WARPLAB_MIMO_4X4_AGC_PLBW_0_BASEADDR); gBB_C = warplab_AGC_ReadReg_GBB_C(XPAR_WARPLAB_MIMO_4X4_AGC_PLBW_0_BASEADDR); gRF_C = warplab_AGC_ReadReg_GRF_C(XPAR_WARPLAB_MIMO_4X4_AGC_PLBW_0_BASEADDR); gBB_D = warplab_AGC_ReadReg_GBB_D(XPAR_WARPLAB_MIMO_4X4_AGC_PLBW_0_BASEADDR); gRF_D = warplab_AGC_ReadReg_GRF_D(XPAR_WARPLAB_MIMO_4X4_AGC_PLBW_0_BASEADDR); // First concatenate the two radios together, into the gRF register // 2 lowest bits are RF, 5 higher bits are BB, last bit is unused // Multiply by 2^2, shift gBB right by 2 bits gRF_A = gRF_A + (gBB_A * 4); gRF_B = gRF_B + (gBB_B * 4); gRF_C = gRF_C + (gBB_C * 4); gRF_D = gRF_D + (gBB_D * 4); // Multiply by 2^8 shift gRF right by 8 bits gains = gRF_A + (gRF_B * 256) + (gRF_C * 65536) + (gRF_D * 16777216); return gains; } void warplab_AGC_SetTarget(unsigned int target) { warplab_AGC_WriteReg_T_dB(target); return; } void warplab_AGC_SetDCO(unsigned int AGCstate) { // Enables DCO and DCO subtraction (correction scheme and butterworth hipass are active) unsigned int bits; bits = warplab_AGC_ReadReg_Bits(XPAR_WARPLAB_MIMO_4X4_AGC_PLBW_0_BASEADDR); if(AGCstate) bits = bits | 0x6; else bits = bits & 0x1; warplab_AGC_WriteReg_Bits(bits); return; }