///@brief Callback for the expiration of timers /// ///This function is responsible for handling #TIMEOUT and #BACKOFF. ///The job responsibilities of this function are to: ///-increase the contention window upon the expiration of a #TIMEOUT ///-initiate a #BACKOFF timer upon the expiration of a #TIMEOUT ///-retransmit a packet upon the expiration of a #BACKOFF ///@param timerType #TIMEOUT or #BACKOFF void timer_callback(unsigned char timerType) { switch(timerType) { case TIMEOUT_TIMER: warpmac_setTimer(BACKOFF_TIMER); break; case BACKOFF_TIMER: if(txMacframe.header.remainingTx) { //Copy the header over to the Tx packet buffer warpmac_prepPhyForXmit(&txMacframe, pktBuf_tx_DATA); //Send from the Tx packet buffer warpmac_startPhyXmit(pktBuf_tx_DATA); //Wait for it to finish warpmac_finishPhyXmit(); //Start a timeout timer warpmac_setTimer(TIMEOUT_TIMER); warpmac_decrementRemainingReSend(&txMacframe); } else { //Either the packet has been sent the max number of times, or // we just got an ACK and need to backoff before starting with a new packet warpmac_enableDataFromNetwork(); } break; //END BACKOFF_TIMER } }
///@brief Main function /// ///This function configures MAC parameters, enables the underlying frameworks, and then loops forever. int main() { xil_printf("HALFMAC Client v16.1: Software-driven Acknowledgments\r\n"); //Assign the packet buffers in the PHY pktBuf_rx = 1; pktBuf_tx_DATA = 2; pktBuf_tx_ACK = 3; //Initialize the framework // This function sets safe defaults for many parameters in the MAC/PHY frameworks // Many of these can be changed with other warpmac_ and warpphy_ calls // or by customizing the warpmac.c/warpphy.c source warpmac_init(); //Read Dip Switch value from FPGA board. //This value will be used as an index into the routing table for other nodes myID = (unsigned short int)warpmac_getMyId(); warpmac_rightHex(myID); //Set the PHY for SISO using just the radio in slot 2 warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA); //Set the packet detection thresholds warpphy_setEnergyDetThresh(7000); //Min RSSI (in [0,16368]) warpphy_setAutoCorrDetParams(90, 0); //Min auto-correlation (in [0,2047]) warpphy_setLongCorrThresh(8000); //Min cross-correlation (in [0,45e3]) //Rx buffer is where the EMAC will DMA Wireless payloads from warpmac_setRxBuffers(&rxMacframe, pktBuf_rx); //Tx buffer is where the EMAC will DMA Ethernet payloads to warpmac_setPHYTxBuffer(pktBuf_tx_DATA); warpmac_setEMACRxBuffer(pktBuf_tx_DATA); //Connect the various user-level callbacks warpmac_setCallback(EVENT_DATAFROMNETWORK, (void *)dataFromNetworkLayer_callback); warpmac_setCallback(EVENT_PHYGOODHEADER, (void *)phyRx_goodHeader_callback); warpmac_setCallback(EVENT_PHYBADHEADER, (void *)phyRx_badHeader_callback); //Set the default center frequency warpphy_setChannel(GHZ_2, 4); lastRxSeqNum = 0; //Enable Ethernet warpmac_enableDataFromNetwork(); while(1) { //Poll the timer, PHY and user I/O forever; actual processing will happen via callbacks above warpmac_pollPeripherals(); } return; }
///@brief Main function /// ///This function configures MAC parameters, enables the underlying frameworks, and then loops forever. int main(){ //Initialize global variables chan = 4; //Assign the packet buffers in the PHY // The auto responder can't transmit from buffer 0, so we use it for Rx packets // The other assignments (DATA/ACK) are arbitrary; any buffer in [1,30] will work pktBuf_rx = 1; pktBuf_tx_DATA = 2; //Set the full-rate modulation to QPSK by default // pktFullRate = HDR_FULLRATE_QPSK; pktFullRate = HDR_FULLRATE_QAM_16; //Set the payload coding rate to 3/4 rate by default pktCodeRate = HDR_CODE_RATE_34; //Initialize the MAC/PHY frameworks warpmac_init(); maximumReSend = 8; warpmac_setMaxResend(maximumReSend); warpmac_setMaxCW(5); warpmac_setTimeout(120); warpmac_setSlotTime(22); //Read Dip Switch value from FPGA board. //This value will be used as an index into the routing table for other nodes myID = (unsigned short int)warpmac_getMyId(); warpmac_rightHex(myID); //Configure the PHY and radios for single antenna (SISO) mode warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA); //warpphy_setAntennaMode(TX_ANTMODE_MULTPLX, RX_ANTMODE_MULTPLX); //warpphy_setAntennaMode(TX_ANTMODE_ALAMOUTI_ANTA, RX_ANTMODE_ALAMOUTI_ANTA); //Set the packet detection thresholds warpphy_setEnergyDetThresh(7000); //Min RSSI (in [0,16368]) warpphy_setAutoCorrDetParams(90, 0); //Min auto-correlation (in [0,2047]) warpphy_setLongCorrThresh(8000); //Min cross-correlation (in [0,45e3]) //Rx buffer is where the EMAC will DMA Wireless payloads from warpmac_setRxBuffers(&rxMacframe, pktBuf_rx); //Tx buffer is where the EMAC will DMA Ethernet payloads to warpmac_setPHYTxBuffer(pktBuf_tx_DATA); warpmac_setEMACRxBuffer(pktBuf_tx_DATA); //Set the modulation scheme use for base rate (header) symbols warpmac_setBaseRate(QPSK); //Copy this node's MAC address into the Tx buffer's source address field txMacframe.header.srcAddr = (unsigned short int)(NODEID_TO_ADDR(myID)); //Register callbacks warpmac_setCallback(EVENT_TIMER, (void *)timer_callback); warpmac_setCallback(EVENT_DATAFROMNETWORK, (void *)dataFromNetworkLayer_callback); warpmac_setCallback(EVENT_PHYGOODHEADER, (void *)phyRx_goodHeader_callback); warpmac_setCallback(EVENT_PHYBADHEADER, (void *)phyRx_badHeader_callback); warpmac_setCallback(EVENT_UARTRX, (void *)uartRecv_callback); //Set the default center frequency warpphy_setChannel(GHZ_2, chan); //Enable carrier sensing warpmac_setCSMA(1); txSeqNum = 0; //halfmac_server doesn't send ACKs, so skip autoResponder setup //Listen for new packets to send (either from Ethernet or local dummy packets) warpmac_enableDataFromNetwork(); xil_printf("Reference Design v16.1 HALFMAC SERVER\r\n"); xil_printf("Beginning main loop\r\n"); while(1) { //Poll the timer, PHY and user I/O forever; actual processing will happen via callbacks above warpmac_pollPeripherals(); } return 0; }
///@brief Main function /// ///This function configures MAC parameters, enables the underlying frameworks, and then loops forever. int main() { xil_printf("HALFMAC Client v16.1: AutoResponder-driven Acknowledgments\r\n"); //Assign the packet buffers in the PHY // The auto responder can't transmit from buffer 0, so we use it for Rx packets // The other assignments (DATA/ACK) are arbitrary; any buffer in [1,30] will work pktBuf_rx = 1; pktBuf_tx_DATA = 2; pktBuf_tx_ACK = 3; //Initialize the framework // This function sets safe defaults for many parameters in the MAC/PHY frameworks // Many of these can be changed with other warpmac_ and warpphy_ calls // or by customizing the warpmac.c/warpphy.c source warpmac_init(); //Read Dip Switch value from FPGA board. //This value will be used as an index into the routing table for other nodes myID = (unsigned short int)warpmac_getMyId(); warpmac_rightHex(myID); //Set the PHY for SISO using just the radio in slot 2 warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA); //Set the packet detection thresholds warpphy_setEnergyDetThresh(7000); //Min RSSI (in [0,16368]) warpphy_setAutoCorrDetParams(90, 0); //Min auto-correlation (in [0,2047]) warpphy_setLongCorrThresh(8000); //Min cross-correlation (in [0,45e3]) //Rx buffer is where the EMAC will DMA Wireless payloads from warpmac_setRxBuffers(&rxMacframe, pktBuf_rx); //Tx buffer is where the EMAC will DMA Ethernet payloads to warpmac_setPHYTxBuffer(pktBuf_tx_DATA); warpmac_setEMACRxBuffer(pktBuf_tx_DATA); //Connect the various user-level callbacks warpmac_setCallback(EVENT_DATAFROMNETWORK, (void *)dataFromNetworkLayer_callback); warpmac_setCallback(EVENT_PHYGOODHEADER, (void *)phyRx_goodHeader_callback); warpmac_setCallback(EVENT_PHYBADHEADER, (void *)phyRx_badHeader_callback); warpmac_setCallback(EVENT_UARTRX, (void *)uartRecv_callback); //Set the default center frequency warpphy_setChannel(GHZ_2, 4); lastRxSeqNum = 0; Macframe templatePkt; /************************************/ /***** AUTO RESPONDER CONFIG *******/ /************************************/ //WORKSHOP PSEUDOCODE: Note, autoresponder functions are not currently part of the API. They are //documented separately at http://warp.rice.edu/trac/wiki/OFDM/MIMO/Docs/AutoResponse //1) Use the PHY_AUTORESPONSE_MATCH_CONFIG macro to make sure that it is only engaged when a // received packet's destination address matches 'myID' // NOTE: Addresses are 2-bytes wide and are located at addr PKTHEADER_INDX_DSTADDR //2) Use the PHY_AUTORESPONSE_MATCH_CONFIG macro to make sure that it is only engaged when a // received packet's type is a DATAPACKET /**********************USER CODE STARTS HERE***************************/ //Setup the PHY's autoResponse system unsigned int autoResp_matchCond; // For CSMA, it is configured to send pktBuf pktBuf_tx_ACK when a good DATA packet is received addressed to this node //Match condition 0: received header's destination address is this node's address autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_DSTADDR, 2, htons(NODEID_TO_ADDR(myID))); mimo_ofdmTxRx_setMatch0(autoResp_matchCond); //Match condition 1: received header's type is PKTTYPE_DATA autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_TYPE, 1, PKTTYPE_DATA); mimo_ofdmTxRx_setMatch1(autoResp_matchCond); /**********************USER CODE ENDS HERE***************************/ //Configure the header translator to use the Rx pkt's src address as the outgoing pkt's dst address // Addresses are two bytes, so two entries in the header translator need to be overridden // Except for these bytes, the ACK pktBuf's contents will be sent unaltered // PHY_HEADERTRANSLATE_SET(templatePktBuf, byteAddrToOverwrite, srcPktBuf, srcByteAddr) PHY_HEADERTRANSLATE_SET(pktBuf_tx_ACK, (PKTHEADER_INDX_DSTADDR+0), pktBuf_rx, (PKTHEADER_INDX_SRCADDR+0)); PHY_HEADERTRANSLATE_SET(pktBuf_tx_ACK, (PKTHEADER_INDX_DSTADDR+1), pktBuf_rx, (PKTHEADER_INDX_SRCADDR+1)); //Create a template ACK packet templatePkt.header.fullRate = HDR_FULLRATE_QPSK; templatePkt.header.codeRate = HDR_CODE_RATE_34; templatePkt.header.length = 0; templatePkt.header.srcAddr = (unsigned short)(NODEID_TO_ADDR(myID)); templatePkt.header.pktType = PKTTYPE_ACK; //Copy the header down to the PHY's packet buffer // This doesn't actually send anything; the autoResponse system will use this template when sending ACKs warpmac_prepPhyForXmit(&templatePkt, pktBuf_tx_ACK); //Action defitions come last; bad things might happen if an action is enabled (set non-zero) before the template pkt is ready. //All actors are disabled during warpphy_init; only load non-zero configurations for actors you intend to use autoResp_delay = 0; //Action 0: send pkt from buf pktBuf_tx_ACK when match0 & match1 & goodPkt, using header translation autoResp_action = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_ACK, PHY_AUTORESPONSE_ACT_TRANS_HDR, autoResp_delay, (PHY_AUTORESPONSE_REQ_MATCH0 | PHY_AUTORESPONSE_REQ_MATCH1 | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT)); //Write the configuration word to the PHY's autoResponder mimo_ofdmTxRx_setAction0(autoResp_action); //Enable Ethernet warpmac_enableDataFromNetwork(); while(1) { //Poll the timer, PHY and user I/O forever; actual processing will happen via callbacks above warpmac_pollPeripherals(); } return; }
///@brief Main function /// ///This function configures MAC parameters, enables the underlying frameworks, and then loops forever. int main() { xil_printf("\fWARPNET Example v18.0\r\n"); //Assign Tx/Rx to packet buffers in the PHY pktBuf_rx = 1; pktBuf_tx = 2; pktBuf_emac_rx = 3; //Set the center frequency chan = 3; //Initialize the sequence number for outgoing packets seqNum = 0; //Set the default full-rate modulation rate pktFullRate = HDR_FULLRATE_QPSK; pktCodeRate = HDR_CODE_RATE_34; //Initialize the framework // This function sets safe defaults for many parameters in the MAC/PHY frameworks // Many of these can be changed with other warpmac_ and warpphy_ calls // or by customizing the warpmac.c/warpphy.c source warpmac_init(); //Read Dip Switch value from FPGA board. //This value will be used as an index into the routing table for other nodes myID = (unsigned short int)warpmac_getMyId(); warpmac_rightHex(myID); //Choose the antnenna mode warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA); //warpphy_setAntennaMode(TX_ANTMODE_ALAMOUTI_ANTA, RX_ANTMODE_ALAMOUTI_ANTA); //warpphy_setAntennaMode(TX_ANTMODE_MULTPLX, RX_ANTMODE_MULTPLX); //Rx buffer is where the EMAC will DMA Wireless payloads from warpmac_setRxBuffers(&rxFrame, pktBuf_rx); //Tx buffer is where the EMAC will DMA Ethernet payloads to warpmac_setEMACRxBuffer(pktBuf_emac_rx); warpmac_setPHYTxBuffer(pktBuf_tx); //Connect the various user-level callbacks warpmac_setCallback(EVENT_DATAFROMNETWORK, (void *)dataFromNetworkLayer_callback); warpmac_setCallback(EVENT_MGMTPKT, (void *)mgmtFromNetworkLayer_callback); warpmac_setCallback(EVENT_PHYGOODHEADER, (void *)phyRx_goodHeader_callback); warpmac_setCallback(EVENT_PHYBADHEADER, (void *)phyRx_badHeader_callback); #ifdef WARP_HW_VER_v3 //Set the OFDM Rx detection thresholds warpphy_setCarrierSenseThresh(4000); //Carrier sense thresh (in [0,16368]) warpphy_setEnergyDetThresh(6500); //Min RSSI (in [0,16368]) warpphy_setAutoCorrDetParams(50, 20); //Min auto-correlation (UFix8_7) and min energy (UFix16_8) warpphy_setLongCorrThresh(10000); //Min cross-correlation (in [0,45e3]) //Set the default Tx gain (in [0,63]) warpphy_setTxPower(50); #else //Set the OFDM Rx detection thresholds (copied from OFDM ref des v17 for now) warpphy_setCarrierSenseThresh(12000); //Carrier sense thresh (in [0,16368]) warpphy_setEnergyDetThresh(7000); //Min RSSI (in [0,16368]) warpphy_setAutoCorrDetParams(90, 20); //Min auto-correlation (UFix8_7) and min energy (UFix16_8) warpphy_setLongCorrThresh(8000); //Min cross-correlation (in [0,45e3]) //Set the default Tx gain (in [0,63]) warpphy_setTxPower(55); #endif //Set the default center frequency warpphy_setChannel(GHZ_2, 11); //Enable dummy packet mode; data packets will only be generated locally warpmac_setDummyPacketMode(1); //Set safe default dummy packet length/intervals; WARPnet will override these per-experiment pktGen_length = 1412; pktGen_period = 10000; //Enable the OFDM Tx random payload generator (so locally generated packets have some non-zero payloads) mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | (TX_RANDOM_PAYLOAD | TX_CAPTURE_RANDOM_PAYLOAD)); //Listen for new packets to send (either from Ethernet or local dummy packets) warpmac_enableDataFromNetwork(); /*** WARPnet Measurement/Control Setup ***/ //Fill in the server/group struct with sane defaults groupStruct.controllerID = 0; groupStruct.controllerGrp = 0; groupStruct.access = 1; groupStruct.reserved0 = 0; perStruct.structID = STRUCTID_OBSERVE_PER; perStruct.nodeID = myID; perStruct.reqNum = 0; perStruct.reqType = 0; perStruct.numPkts_tx = 0; perStruct.numPkts_rx_good = 0; perStruct.numPkts_rx_goodHdrBadPyld = 0; perStruct.numPkts_rx_badHdr = 0; //Disable reporting of packets for BER testing (WARPnet may enable at runtime) reportBERviaWarpnet = 0; //Fill in the Ethernet packet header templates txEthPktHeader.ethType = WARPNET_ETHTYPE_NODE2SVR; txEthPktHeader.srcAddr[0]=0x00; txEthPktHeader.srcAddr[1]=0x50; txEthPktHeader.srcAddr[2]=0xC2; txEthPktHeader.srcAddr[3]=0x63; txEthPktHeader.srcAddr[4]=0x3F; txEthPktHeader.srcAddr[5]=0x80+myID; /****************************** NOTE ********************************/ /* You should fill in the MAC address of your WARPnet server here! */ /*******************************************************************/ txEthPktHeader.dstAddr[0]=0xff; txEthPktHeader.dstAddr[1]=0xff; txEthPktHeader.dstAddr[2]=0xff; txEthPktHeader.dstAddr[3]=0xff; txEthPktHeader.dstAddr[4]=0xff; txEthPktHeader.dstAddr[5]=0xff; txEthPktHeader.numStructs = 1; coprocEthPktHeader.ethType = WARPNET_ETHTYPE_NODE2BER; coprocEthPktHeader.srcAddr[0]=0x00; coprocEthPktHeader.srcAddr[1]=0x50; coprocEthPktHeader.srcAddr[2]=0xC2; coprocEthPktHeader.srcAddr[3]=0x63; coprocEthPktHeader.srcAddr[4]=0x3F; coprocEthPktHeader.srcAddr[5]=0x80+myID; /****************************** NOTE ********************************/ /* You should fill in the MAC address of your WARPnet server here! */ /*******************************************************************/ coprocEthPktHeader.dstAddr[0]=0xff; coprocEthPktHeader.dstAddr[1]=0xff; coprocEthPktHeader.dstAddr[2]=0xff; coprocEthPktHeader.dstAddr[3]=0xff; coprocEthPktHeader.dstAddr[4]=0xff; coprocEthPktHeader.dstAddr[5]=0xff; coprocEthPktHeader.numStructs = 1; while(1) { //Poll the timer, PHY and user I/O forever; actual processing will happen via callbacks above warpmac_pollPeripherals(); } return 0; }