source: ResearchApps/MAC/DOCMAC/docMac.c

Last change on this file was 1496, checked in by murphpo, 14 years ago

bug fix

  • Property svn:executable set to *
File size: 55.1 KB
RevLine 
[1244]1/*! \file doc.c
2 \brief Distributed On-Demand Cooperation
[1174]3 
[1496]4 @version 15
[1231]5 @author Chris Hunter and Patrick Murphy
[1174]6 
7 
8 */
9#include "warpmac.h"
[1486]10#include "warpnet.h"
[1174]11#include "warpphy.h"
12#include "docMac.h"
13#include "xparameters.h"
[1231]14#include "ofdm_txrx_mimo_regMacros.h"
[1174]15#include "string.h"
16#include "errno.h"
17#include "stdlib.h"
18#include "stdio.h"
19#include "ascii_characters.h"
20#include "warp_userioboard_util.h"
[1253]21#include "radio_controller_ext.h"
[1486]22#include "xtime_l.h"
[1174]23
[1469]24
25
26#define PERLOW  80000
27#define PERHIGH 60000
28#define DUTYLOW 13107
29#define DUTYHIGH 13107
30
[1461]31#define htons(A) ((((Xuint16)(A) & 0xff00) >> 8) | (((Xuint16)(A) & 0x00ff) << 8))
[1259]32#define MAX_NUMNODES 3
[1231]33
[1244]34#define REQ_DST_ME PHY_AUTORESPONSE_REQ_MATCH0
35#define REQ_RLY_ME PHY_AUTORESPONSE_REQ_MATCH1
36#define REQ_DATA PHY_AUTORESPONSE_REQ_MATCH2
37#define REQ_NACK PHY_AUTORESPONSE_REQ_MATCH3
38
[1259]39#define NUM_RX_PKTBUFS 2
[1244]40
[1469]41
42
[1259]43unsigned char randomData_Mode;
44
[1231]45Macframe templatePkt;
46unsigned int autoResp_matchCond;
47unsigned int autoResp_action;
[1259]48unsigned int autoResp_action_reTx;
49unsigned int autoResp_action_coopTx;
[1266]50unsigned short autoRespDelay_NACKTx, autoRespDelay_AFTx, autoRespDelay_ReTx, autoRespDelay_ACKTx;
[1279]51unsigned int docPreambleScaling,docPayloadScaling;
[1467]52unsigned int txPower;
[1259]53
[1267]54unsigned char relayDestID;
55unsigned int relayLen;
[1486]56unsigned char alternating;
57unsigned char currentAlt;
[1267]58
[1486]59XTime startTime;
60XTime stopTime;
61
[1231]62unsigned char pktBuf_tx_ACK;
63unsigned char pktBuf_tx_NACK;
64unsigned char pktBuf_tx_DATA;
[1486]65unsigned char pktBuf_rx_emac;
[1231]66unsigned char pktBuf_tx_AF;
67unsigned char pktBuf_rx;
[1259]68unsigned char rxPktBufs[NUM_RX_PKTBUFS];
69unsigned char pktBuf_rx_ind;
[1279]70unsigned char respondToNacks;
[1259]71
[1231]72unsigned char relayMode;
73unsigned short relayMode_lastSrcAddr;
[1259]74
[1486]75unsigned char enableStats;
76int pktGen_length;
77int pktGen_period;
78unsigned char enablePktGen;
79unsigned char allowRelay;
80
[1244]81unsigned short rx_correThresh;
82unsigned char cfoDly;
83unsigned char ignoreSeqNums;
[1259]84unsigned char cfoVar;
[1244]85unsigned char agcPrintMode;
86unsigned int pktDet_rssi;
87unsigned int agcGains;
[1263]88unsigned char antB_preambleShift;
[1244]89unsigned char debug_sisoMode;
[1174]90unsigned char userIOBoard_LEDs;
91unsigned char charsToPrint[16];
[1231]92unsigned int pktCount_good, pktCount_bad;
[1174]93
[1486]94unsigned short int rxSequences[MAX_NUMNODES];
95unsigned short int txSequences[MAX_NUMNODES];
[1174]96
[1259]97unsigned char max_numTransmissions;
[1174]98
99///Index to the routing table that identifies this node
[1231]100unsigned short int myID;
[1174]101
102///Full rate modulation selection; QPSK by default
103unsigned int pktFullRate;
104
105//Payload code rate selection; must be CODE_RATE_NONE for uncoded PHY
106unsigned int pktCodeRate;
107
[1486]108#define NUMMODES 2
109
110unsigned int stats_numDataTx[MAX_NUMNODES][MAX_NUMNODES][NUMMODES];
111unsigned int stats_numNACKTx[MAX_NUMNODES][MAX_NUMNODES][NUMMODES];
112unsigned int stats_numDataRx[MAX_NUMNODES][MAX_NUMNODES][NUMMODES];
113unsigned int stats_numNACKRx[MAX_NUMNODES][MAX_NUMNODES][NUMMODES];
114unsigned int stats_sumGains[MAX_NUMNODES][MAX_NUMNODES][NUMMODES];
115unsigned int stats_sumPacketsRx[MAX_NUMNODES][MAX_NUMNODES][NUMMODES];
116unsigned int stats_sumRSSI[MAX_NUMNODES][MAX_NUMNODES][NUMMODES];
117unsigned int stats_numBadHeaderRx;
118
[1174]119///Buffer for holding a packet-to-xmit across multiple retransmissions
120Macframe txBuffer;
121///Buffer to hold received packet
122Macframe rxBuffer;
123
124///Current antenna selection
125unsigned char currentAnt;
126///Current 802.11 channel
127unsigned char chan;
128
[1469]129unsigned char buzzerEnable;
130
[1231]131//Define handy macros for MAC packet types
132///ACK/NACK packet types
[1174]133#define ACKPACKET 0
[1231]134#define NACKPACKET 1
135///Data packet types
136#define DATAPACKET 2
[1174]137
[1253]138// Aid for Debugging Purposes, if 1 print from Teraterm
139#define PrintDebug 0
140
[1486]141warpnetEthernetPktHeader txEthPktHeader;
[1253]142
143
[1486]144void resetStats(){
145int i,j,k;
[1267]146
[1486]147for(i=0;i<MAX_NUMNODES;i++){
148    for(j=0;j<MAX_NUMNODES;j++){
149        for(k=0;k<NUMMODES;k++){
150            stats_numDataTx[i][j][k]=0;
151            stats_numNACKTx[i][j][k]=0;
152            stats_numDataRx[i][j][k]=0;
153            stats_numNACKRx[i][j][k]=0; 
154            stats_sumGains[i][j][k]=0;
155            stats_sumPacketsRx[i][j][k]=0;
156            stats_sumRSSI[i][j][k]=0;
157        }
158    }
[1253]159}
160
[1486]161stats_numBadHeaderRx=0;
[1253]162}
163
[1486]164
[1174]165///@brief Callback for the depression of the left push button
166///
167///This function is empty by default
168void left(){
[1486]169//  xil_printf("stats_numDataTx      = %d\r\n",stats_numDataTx);
170//  xil_printf("stats_numDataRx      = %d\r\n",stats_numDataRx);
171//  xil_printf("numRelayTx     = %d\r\n",numRelayTx);
172//  xil_printf("stats_numBadHeaderRx = %d\r\n",stats_numBadHeaderRx);
173//  xil_printf("stats_numNACKTx      = %d\r\n",stats_numNACKTx);
174//  xil_printf("stats_numNACKRx      = %d\r\n",stats_numNACKRx);
[1174]175}
176
177///@brief Callback for the depression of the right push button
178///
179///This button switched between different fullrate modulation orders
180void right(){
[1486]181//  stats_numDataTx=0;
182//  stats_numDataRx=0;
183//  stats_numBadHeaderRx=0;
184//  stats_numNACKTx=0;
185//  stats_numNACKRx=0;
186//  numRelayTx = 0;
[1174]187}
188
189///@brief Callback for the depression of the up push button
190///
191///This button increments the 2.4GHz channel being used; only valid channels (in [1,14]) will be used
192void up(){
[1469]193    buzzerEnable = 1;
[1174]194}
195
196///@brief Callback for the depression of the middle push button
197///
198///This button decrements the 2.4GHz channel being used; only valid channels (in [1,14]) will be used
199void middle(){
[1469]200    buzzerEnable  = 0;
[1174]201}
202
203///@brief Updates the LCD
204///
205///Updates the LCD. This is only for the User I/O daughtercard. If you do not have this card,
206///this function will do nothing. This operation takes some time, so it can only be called in a few places so as to
207///not adversely affect the performance of the MAC.
208void updateLCD()
209{
210
[1486]211//  warp_userioboard_set_leds(userIOBoard_LEDs);   
212//  snprintf(charsToPrint, 16, "Good: %09d ", pktCount_good);
213//  warp_userio_lcd_printline(charsToPrint, 16, 4, 1);
214//  snprintf(charsToPrint, 16, "Bad:  %09d ", (pktCount_bad)>>1);//bad pkts get counted twice
215//  warp_userio_lcd_printline(charsToPrint, 16, 5, 1);
[1174]216   
217    return;
218}
219
220///@brief Callback for the reception of UART bytes
221///@param uartByte ASCII byte received from UART
222///
223///Provides the user with the bytes that was received over the serial port. This is useful for configuring
224///PHY and MAC parameters in real time on a board.
225void uartRecv_callback(unsigned char uartByte)
226{
227    if(uartByte != 0x0)
228    {
229        xil_printf("(%c)\t", uartByte);
230       
231        switch(uartByte)
232        {
[1279]233            case ASCII_W:
234                docPreambleScaling+=10;
235                mimo_ofdmTx_setTxScaling(docPreambleScaling,docPayloadScaling);
236                xil_printf("+Preamble Scaling: %d\r\n",docPreambleScaling);
237                break;
238               
239            case ASCII_w:
240                docPreambleScaling-=10;
241                mimo_ofdmTx_setTxScaling(docPreambleScaling,docPayloadScaling);
242                xil_printf("-Preamble Scaling: %d\r\n",docPreambleScaling);
243                break;
244               
245            case ASCII_E:
246                docPayloadScaling+=10;
247                mimo_ofdmTx_setTxScaling(docPreambleScaling,docPayloadScaling);
248                xil_printf("+Payload Scaling: %d\r\n",docPayloadScaling);
249                break;
250               
251            case ASCII_e:
252                docPayloadScaling-=10;
253                mimo_ofdmTx_setTxScaling(docPreambleScaling,docPayloadScaling);
254                xil_printf("-Payload Scaling: %d\r\n",docPayloadScaling);               
255                break;
256               
[1174]257            case ASCII_1:
258                pktFullRate = HDR_FULLRATE_BPSK;
259                xil_printf("Tx Full Rate = BPSK\r\n");
260                break;
261               
262            case ASCII_2:
263                pktFullRate = HDR_FULLRATE_QPSK;
264                xil_printf("Tx Full Rate = QPSK\r\n");
265                break;
266               
267            case ASCII_4:
268                pktFullRate = HDR_FULLRATE_QAM_16;
269                xil_printf("Tx Full Rate = 16-QAM\r\n");
270                break;
271               
[1259]272            case ASCII_5:
273                randomData_Mode=(randomData_Mode+1)%2;
274                xil_printf("randomData_Mode: %d\r\n",randomData_Mode);
275                break;
276
277               
[1174]278            case ASCII_6:
279                pktFullRate = HDR_FULLRATE_QAM_64;
280                xil_printf("Tx Full Rate = 64-QAM\r\n");
281                break;
[1279]282           
[1244]283            case ASCII_8:
284                debug_sisoMode = (debug_sisoMode ^ 1) & 0x1;
285                if(debug_sisoMode){
286                    warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA);
287                }
288                else{
289                    warpphy_setAntennaMode(TX_ANTMODE_ALAMOUTI_ANTA, RX_ANTMODE_ALAMOUTI_ANTA);
290                }
291                xil_printf("SISO mode = %d\r\n", debug_sisoMode);
292
293                break;
294            case ASCII_9:
295                agcPrintMode = (agcPrintMode ^ 1) & 0x1;
296                break;
[1279]297
[1231]298            case ASCII_O:
299                warpphy_set_FFTOffset_Plus();
300                break;
301            case ASCII_o:
302                warpphy_set_FFTOffset_Minus();
303                break;
[1174]304            case ASCII_F:
305                if(chan<14) chan++;
306                warpphy_setChannel(GHZ_2, chan);
307                xil_printf("Current channel: %d\r\n",chan);
308                break;
309            case ASCII_f:
310                if(chan>1) chan--;
311                warpphy_setChannel(GHZ_2, chan);
312                xil_printf("Current channel: %d\r\n",chan);
313                break;
[1231]314            case ASCII_G:
[1467]315                txPower++;
316                warpphy_setTxPower(txPower);
317                xil_printf("New Tx Power = 0x%x\r\n",txPower);
[1231]318                break;
319            case ASCII_g:
[1467]320                txPower--;
321                warpphy_setTxPower(txPower);
322                xil_printf("New Tx Power = 0x%x\r\n",txPower);
[1231]323                break;
[1174]324            case ASCII_C:
[1231]325                ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) | COARSE_CFO_EN);
326                xil_printf("Coarse CFO Enabled\r\n");
[1174]327                break;
328            case ASCII_c:
[1231]329                ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) & ~(COARSE_CFO_EN));
330                xil_printf("Coarse CFO Disabled\r\n");
[1174]331                break;
332            case ASCII_A:
[1279]333                xil_printf("AF/ReTx enabled\r\n");
334                respondToNacks = 1;
[1174]335                break;
336            case ASCII_a:
[1279]337                xil_printf("AF/ReTx disabled\r\n");
338                respondToNacks = 0;
[1174]339                break;
[1244]340            case ASCII_t:
341                rx_correThresh = rx_correThresh - 50;
342                warpphy_setLongCorrThresh(rx_correThresh);
343                break;
344            case ASCII_T:
345                rx_correThresh = rx_correThresh + 50;
346                warpphy_setLongCorrThresh(rx_correThresh);
347                break;
348
[1259]349            case ASCII_V:
350                cfoVar++;
351                mimo_ofdmRx_setCFOMaxDiff(cfoVar);
352                xil_printf("cfoVar = %d\r\n",cfoVar);
353                break;
354            case ASCII_v:
355                cfoVar--;
356                mimo_ofdmRx_setCFOMaxDiff(cfoVar);
357                xil_printf("cfoVar = %d\r\n",cfoVar);
358                break;
359
360               
[1244]361            case ASCII_J:
362                cfoDly++;
363                mimo_ofdmRx_setCFOCalcDly(cfoDly);
364                xil_printf("CFO delay: %d\r\n", cfoDly);
365                break;
366            case ASCII_j:
367                cfoDly--;
368                mimo_ofdmRx_setCFOCalcDly(cfoDly);
369                xil_printf("CFO delay: %d\r\n", cfoDly);
370                break;
371               
[1279]372            case ASCII_x:
[1461]373                //warpmac_uhoh();
[1279]374                break;
[1244]375               
[1279]376               
[1231]377            case ASCII_S:
[1461]378                //warpphy_setAFScalingPlus();
[1231]379                break;
380               
381            case ASCII_s:
[1461]382                //warpphy_setAFScalingMinus();
[1231]383                break;
[1244]384           
385            case ASCII_P:
386                warpphy_setPktDetPlus(200);
387                break;
388
389            case ASCII_p:
390                warpphy_setPktDetMinus(200);
391                break;
392               
[1263]393            case ASCII_B:
[1467]394                //antB_preambleShift++;
395                //warpphy_setAntBPreambleShift(antB_preambleShift);
396                //xil_printf("AntB Preamble Shift: %d\r\n", antB_preambleShift);
[1263]397                break;
398               
399            case ASCII_b:
[1467]400                //antB_preambleShift--;
401                //warpphy_setAntBPreambleShift(antB_preambleShift);
402                //xil_printf("AntB Preamble Shift: %d\r\n", antB_preambleShift);
[1263]403                break;
404               
[1259]405            case ASCII_R:
[1263]406                autoRespDelay_AFTx++;
407                autoRespDelay_ReTx++;
408                xil_printf("autoRespDelay_AFTx: %d - autoRespDelay_ReTx: %d\r\n", autoRespDelay_AFTx, autoRespDelay_ReTx);
[1231]409                break;
410               
411            case ASCII_r:
[1263]412                autoRespDelay_AFTx--;
413                autoRespDelay_ReTx--;
414                xil_printf("autoRespDelay_AFTx: %d - autoRespDelay_ReTx: %d\r\n", autoRespDelay_AFTx, autoRespDelay_ReTx);
[1231]415                break;
[1259]416           
[1244]417               
418            case ASCII_q:
419                ignoreSeqNums = (ignoreSeqNums ^ 1)%2;
420                xil_printf("Ignore seq nums: %d\r\n", ignoreSeqNums);
421                break;
422
[1231]423            case ASCII_N:
[1492]424//              autoRespDelay_NACKTx++;
425//  autoResp_action = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_NACK, PHY_AUTORESPONSE_ACT_TRANS_HDR, autoRespDelay_NACKTx, (REQ_DST_ME | REQ_DATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT)); //Use for NACKs in place of ACKs
426//              mimo_ofdmTxRx_setAction1(autoResp_action);
427//              xil_printf("NACK delay: %d\r\n", autoRespDelay_NACKTx);
[1231]428                break;
429               
430            case ASCII_n:
[1492]431//              autoRespDelay_NACKTx--;
432//  autoResp_action = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_NACK, PHY_AUTORESPONSE_ACT_TRANS_HDR, autoRespDelay_NACKTx, (REQ_DST_ME | REQ_DATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT)); //Use for NACKs in place of ACKs
433//              mimo_ofdmTxRx_setAction1(autoResp_action);
434//              xil_printf("NACK delay: %d\r\n", autoRespDelay_NACKTx);
[1231]435                break;
[1263]436
[1266]437            case ASCII_Z:
438                autoRespDelay_ACKTx++;
439                autoResp_action = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_ACK, 1, autoRespDelay_ACKTx, (REQ_DST_ME | REQ_DATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
440                mimo_ofdmTxRx_setAction0(autoResp_action);
441                xil_printf("ACK delay: %d\r\n", autoRespDelay_ACKTx);
442                break;
443
444            case ASCII_z:
445                autoRespDelay_ACKTx--;
446                autoResp_action = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_ACK, 1, autoRespDelay_ACKTx, (REQ_DST_ME | REQ_DATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
447                mimo_ofdmTxRx_setAction0(autoResp_action);
448                xil_printf("ACK delay: %d\r\n", autoRespDelay_ACKTx);
449                break;
[1279]450               
451            case ASCII_m:
452               
453                break;
454               
[1174]455            default:
456                xil_printf("Undefined command\r\n");
457                break;
458        }
459    }
460   
461    return;
462}
463///@brief Callback for the expiration of timers
464///
465///This function is responsible for handling #TIMEOUT and #BACKOFF.
466///The job responsibilities of this function are to:
467///-increase the contention window upon the expiration of a #TIMEOUT
468///-initiate a #BACKOFF timer upon the expiration of a #TIMEOUT
469///-retransmit a packet upon the expiration of a #BACKOFF
470///@param timerType #TIMEOUT or #BACKOFF
471void timer_callback(unsigned char timerType){
472    switch(timerType){
[1469]473   
474        case BUZZER_TIMER:
475       
476            warp_userioboard_set_buzzer_en(0);
477        //  xil_printf("!\r\n");
478        break;
[1186]479        case TIMEOUT_TIMER:
[1486]480       
[1259]481            if(!relayMode)
482            {
483                //Source sent a DATA but never got ACK or NACK; time to re-transmit or give up
[1231]484               
[1259]485                //Check if this will be our last transmission attempt
486                if(txBuffer.remainingTx == 1)
487                {
[1266]488                    //Disable the auto-retransmitter, in case a NACK is received after a relay transmission during our backoff
489                    autoResp_action_reTx = 0;
490                    mimo_ofdmTxRx_setAction2(autoResp_action_reTx);
491
[1259]492                    //Overwrite the relay address to our own, disabling cooperation from now on
[1492]493                    txBuffer.header.relAddr = NODEID_TO_ADDR(myID);
[1259]494                   
495                    //Copy the updated header down to the PHY pkt buffer
496                    warpmac_prepPhyForXmit(&txBuffer, pktBuf_tx_DATA);
497                }
498               
499                //Start a random backoff before attempting to re-transmit
500                warpmac_setTimer(BACKOFF_TIMER);
501            }
502            else //relayMode == 1
503            {
504                //Relay never got a ACK or NACK, so disable the autoResponse actor for cooperative transmissions
[1471]505               
506               
507               
[1259]508                autoResp_action_coopTx = 0;
509                mimo_ofdmTxRx_setAction4(autoResp_action_coopTx);
510               
[1267]511
[1486]512
[1267]513               
514               
[1259]515                //De-assert relay mode
[1231]516                relayMode = 0;
[1259]517               
518                //Clear autoResponse FLAGA (was set by previous reception of DATA)
519                warpphy_clearAutoResponseFlag(AUTORESP_FLAGID_A);
520               
521                //Re-enable capture of AF waveforms
[1490]522                //warpmac_setDebugGPIO(0xF);
[1259]523                warpphy_AFrecordEnable(1);
[1231]524            }
[1259]525        break;//END TIMEOUT_TIMER
[1231]526
[1186]527        case BACKOFF_TIMER:
[1259]528            if(txBuffer.remainingTx == 0)
529            {
530                //No more re-transmissions for this packet; discard it and return
531                //Re-enable new packet handling (effectively discards current packet)
532                warpmac_enableDataFromNetwork();
533            }
534            else
535            {
[1261]536                if(txBuffer.remainingTx == 1)
537                {
538                    //Disable the autoResponder for data re-transmissions (it already started its last transmission)
539                    autoResp_action_reTx = 0;
540                    mimo_ofdmTxRx_setAction2(autoResp_action_reTx);
541                }
542               
[1259]543                //Re-transmit the packet
[1231]544                warpmac_startPhyXmit(pktBuf_tx_DATA);
545
[1259]546                //Wait for it to finish
[1174]547                warpmac_finishPhyXmit();
[1279]548                            warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA_SWAPPED);
[1259]549                //Start the timeout interval immediately after the Tx finishes
550                warpmac_setTimer(TIMEOUT_TIMER);
[1231]551
[1259]552                //Decrement the packet's remaining transmisisons
553                txBuffer.remainingTx = txBuffer.remainingTx - 1;
[1263]554               
[1486]555               
[1174]556            }
[1259]557        break;//END BACKOFF_TIMER
[1174]558    }
559}
560
561
[1486]562void processCommand(warpnetCommand* commandStruct){
563    //xil_printf("Process Command Packet\r\n");
564    switch(commandStruct->cmdID){
565        case COMMANDID_STARTTRIAL:
566//          xil_printf("Starting trial\r\n");
567            resetStats();
568            if(enablePktGen) warpmac_startPacketGeneration(pktGen_length, pktGen_period);
569            XTime_GetTime(&startTime);
570            enableStats = 1;
571        break;
572        case COMMANDID_STOPTRIAL:
573//          xil_printf("Stopping trial\r\n");
574            enableStats=0;
575            XTime_GetTime(&stopTime);
576            warpmac_stopPacketGeneration();
577           
578        break;
579        case COMMANDID_PKTGEN:
580            if(commandStruct->cmdParam==COMMANDPARAM_ENABLE){
581                enablePktGen=1;
582//              xil_printf("Enabled Packet Generation\r\n");
583            }
584           
585            if(commandStruct->cmdParam==COMMANDPARAM_DISABLE){
586                enablePktGen=0;
587//              xil_printf("Disabled Packet Generation\r\n");
588            }
589        break;
590        case COMMANDID_RELAYSTATE:
591            if(commandStruct->cmdParam==COMMANDPARAM_OFF){
592                allowRelay=0;
593                alternating=0;
594            }
595            else if(commandStruct->cmdParam==COMMANDPARAM_AF){
596                allowRelay=1;
597            }
598            else if(commandStruct->cmdParam==COMMANDPARAM_ALTERNATING){
599                alternating=1;
600            }
601        break;
602           
603    }
604}
605
606void processRequest(warpnetRequest* requestStruct, warpnetObserve* observeStruct, char mode){
607    //xil_printf("Processing Request: NodeID = %d, cmdID = %d\r\n",myID,requestStruct->cmdID);
608    observeStruct->structID=STRUCTID_OBSERVE;
609    observeStruct->nodeID=myID;
610    observeStruct->sourceNode=requestStruct->cmdID;
611    observeStruct->numDataTx=stats_numDataTx[requestStruct->cmdID][myID][mode];
612    observeStruct->numNACKTx=stats_numNACKTx[requestStruct->cmdID][myID][mode];
613    observeStruct->numDataRx=stats_numDataRx[myID][requestStruct->cmdID][mode];
614    observeStruct->numNACKRx=stats_numNACKRx[myID][requestStruct->cmdID][mode];
615    observeStruct->numBadHeaderRx=stats_numBadHeaderRx;
616    observeStruct->sumGains=stats_sumGains[myID][requestStruct->cmdID][mode];
617    observeStruct->sumRSSI=stats_sumRSSI[myID][requestStruct->cmdID][mode];
618    observeStruct->sumPacketCountRx=stats_sumPacketsRx[myID][requestStruct->cmdID][mode];
619   
620    //xil_printf("sumPacketCountRx = %d \r\n",stats_sumPacketsRx[myID][requestStruct->cmdID][mode]);
621   
622    observeStruct->trialDuration = stopTime-startTime;
623//  XTime_GetTime(&(observeStruct->timeStamp));
624
625
626//xil_printf("Requested gains = %d\r\n",stats_sumGains[myID][requestStruct->cmdID]);
627//xil_printf("Saved gains = %d\r\n",stats_sumGains[myID][0]);
628
629}
630
631void processControl(warpnetControl* controlStruct){
632    pktGen_length = controlStruct->pktGen_length;
633    pktGen_period = controlStruct->pktGen_period;
[1492]634    chan = controlStruct->channel;
635    warpphy_setChannel(GHZ_2, chan);
636   
637    xil_printf("Channel = %d\r\n",chan);
[1486]638    //xil_printf("LEN: %d, Period: %d\r\n",pktGen_length,pktGen_period);
639}
640
[1253]641///@brief Callback for the reception of Ethernet Management packets
642///
643///This function is called by the ethernet MAC drivers
644///and process the packet to perform specific operations
645///depending on the packet struct
646///@param length Length, in bytes, of received Ethernet frame
[1486]647///@brief Callback for the reception of Ethernet Management packets
648///
649///This function is called by the ethernet MAC drivers
650///and process the packet to perform specific operations
651///depending on the packet struct
652///@param length Length, in bytes, of received Ethernet frame
[1253]653void mgmtFromNetworkLayer_callback(Xuint32 length, char* payload){
654
[1486]655//xil_printf("MGMT RX!\r\n");
656
657    int pktBuf_payloadAddr;
658    warpnetEthernetPktHeader* receivedPkt;
659    warpnetControllerGroup* copyStruct;
660    warpnetCommand* commandStruct;
661    warpnetControl* controlStruct;
662    warpnetRequest* requestStruct;
663    warpnetAck ackStruct;
664    warpnetObserve observeStruct;
665    int sizeofcopy,rxPktOffset,numRxStructs,rxSeqNum,i,thisStructType;
666    sizeofcopy = sizeof(warpnetControllerGroup);
667    receivedPkt = (warpnetEthernetPktHeader*) payload;
668       
669    //If this is a WARPnet Ethernet packet, process it immediately
670    if((receivedPkt->ethType) == WARPNET_ETHTYPE_SVR2NODE){
671        rxPktOffset = sizeof(warpnetEthernetPktHeader);
672        numRxStructs = receivedPkt->numStructs;
673        rxSeqNum = receivedPkt->seqNum;
674       
675        //Itereate over each struct in the Ethernet packet
676        for(i=0; i<numRxStructs; i++)
677        {
678            //Punt if numStructs would have us march past the end of the received packet
679            if(rxPktOffset >= length)
680            {
681                xil_printf("Error! Mgmt pktLength too short for numStructs\r\n");
682                return;
683            }
684           
685            copyStruct = (warpnetControllerGroup*)(payload+rxPktOffset);
686           
687            //Extract the struct type (always the first byte of a struct)
688            thisStructType = *(unsigned char*)(payload+rxPktOffset+sizeofcopy);
689            switch(thisStructType)
690            {
691                case STRUCTID_COMMAND:
692                    commandStruct = (warpnetCommand*)(payload+rxPktOffset+sizeofcopy);
693                    if((commandStruct->nodeID) == myID){
694
695                        ackStruct.structID = STRUCTID_COMMAND_ACK;
696                        ackStruct.nodeID = myID;
697                        ackStruct.cmdID = commandStruct->cmdID;
698                       
699                        txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetAck) + sizeofcopy;
700                        txEthPktHeader.numStructs = 1;
701                       
702                        pktBuf_payloadAddr = warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
703                        memcpy((void *)pktBuf_payloadAddr, &(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
704                        memcpy((void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader), copyStruct, sizeofcopy);
705                        memcpy((void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader)+sizeofcopy, &(ackStruct), sizeof(warpnetAck));
706                       
707                        warpmac_prepPktToNetwork((void *)pktBuf_payloadAddr, txEthPktHeader.pktLength);
708                        warpmac_startPktToNetwork(txEthPktHeader.pktLength);
709                        processCommand(commandStruct);
710                    }
711                    rxPktOffset += sizeof(warpnetCommand);
712                    break;
713                case STRUCTID_CONTROL:
714                    controlStruct = (warpnetControl*)(payload+rxPktOffset+sizeofcopy);
715                    if((controlStruct->nodeID) == myID){
716
717                        ackStruct.structID = STRUCTID_CONTROL_ACK;
718                        ackStruct.nodeID = myID;
719                       
720                        txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetAck) + sizeofcopy;
721                        txEthPktHeader.numStructs = 1;
722                       
723                        pktBuf_payloadAddr = warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
724                        memcpy((void *)pktBuf_payloadAddr, &(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
725                        memcpy((void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader), copyStruct, sizeofcopy);
726                        memcpy((void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader)+sizeofcopy, &(ackStruct), sizeof(warpnetAck));
727                       
728                        warpmac_prepPktToNetwork((void *)pktBuf_payloadAddr, txEthPktHeader.pktLength);
729                        warpmac_startPktToNetwork(txEthPktHeader.pktLength);
730                        processControl(controlStruct);
731                    }
732                   
733                    rxPktOffset += sizeof(warpnetControl);
734                    break;
735                case STRUCTID_OBSERVE_REQUEST_NORELAY:
736                    requestStruct = (warpnetRequest*)(payload+rxPktOffset+sizeofcopy);
737                    if((requestStruct->nodeID) == myID){
738                        processRequest(requestStruct,&observeStruct,0);
739                        txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetObserve) + sizeofcopy;
740                        txEthPktHeader.numStructs = 1;
741                       
742                        pktBuf_payloadAddr = warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
743                        memcpy((void *)pktBuf_payloadAddr, &(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
744                        memcpy((void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader), copyStruct, sizeofcopy);
745                        memcpy((void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader)+sizeofcopy, &(observeStruct), sizeof(warpnetObserve));
746                       
747                        warpmac_prepPktToNetwork((void *)pktBuf_payloadAddr, txEthPktHeader.pktLength);
748                        warpmac_startPktToNetwork(txEthPktHeader.pktLength);
749                    }
750                   
751                    rxPktOffset += sizeof(warpnetControl);
752                    break;
753                case STRUCTID_OBSERVE_REQUEST_RELAY:
754                    requestStruct = (warpnetRequest*)(payload+rxPktOffset+sizeofcopy);
755                    if((requestStruct->nodeID) == myID){
756                        processRequest(requestStruct,&observeStruct,1);
757                        txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetObserve) + sizeofcopy;
758                        txEthPktHeader.numStructs = 1;
759                       
760                        pktBuf_payloadAddr = warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
761                        memcpy((void *)pktBuf_payloadAddr, &(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
762                        memcpy((void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader), copyStruct, sizeofcopy);
763                        memcpy((void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader)+sizeofcopy, &(observeStruct), sizeof(warpnetObserve));
764                       
765                        warpmac_prepPktToNetwork((void *)pktBuf_payloadAddr, txEthPktHeader.pktLength);
766                        warpmac_startPktToNetwork(txEthPktHeader.pktLength);
767                    }
768                   
769                    rxPktOffset += sizeof(warpnetControl);
770                    break;
771            }/* END switch(thisStructType) */
772           
773        }/* END for(numRxStructs) */
774    }/* END if(warpNet packet) */
775   
776    return;
777
778
[1269]779}
780
[1174]781///@brief Callback for the reception of Ethernet packets
782///
783///This function is called by the ethernet MAC drivers
784///when a packet is available to send. This function fills
785///the Macframe transmit buffer with the packet and sends
786///it over the OFDM link
787///@param length Length, in bytes, of received Ethernet frame
[1231]788void dataFromNetworkLayer_callback(Xuint32 length, char* payload){
[1259]789
[1174]790    unsigned char rxSeqNum;
791    unsigned char destNode;
[1231]792    unsigned char relayNode;
[1486]793   
794    warpnetRTObserve rtObserve;
795    warpnetControllerGroup controllerGroup;
796    XTime timeStamp;
797   
798    XTime_GetTime(&timeStamp);
[1259]799
[1486]800   
[1461]801
[1486]802//  xil_printf("data from network Layer\r\n");
[1461]803
[1259]804    //Disable any new packets until we're finished with this one
[1231]805    warpmac_disableDataFromNetwork();
806
[1279]807    warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA);
808   
[1259]809    //Reset the contention window to its smallest size for this exchange
810    warpmac_resetCurrentCW();
[1244]811
[1261]812    //Update the Tx pkt buffer index if we're cycling through them (for non-Ethernet traffic testing only)
[1486]813    if(randomData_Mode){
814        pktBuf_tx_DATA = (((pktBuf_tx_DATA+1)%25) + 4);
815        warpmac_setPHYTxBuffer(pktBuf_tx_DATA);
816    }
[1261]817
[1486]818
[1259]819    //Define and enable the autoResponse actor for sending our retransmissions when NACKs are received
820    autoResp_action_reTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_DATA, 0, autoRespDelay_ReTx, (REQ_DST_ME | REQ_NACK | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
821    mimo_ofdmTxRx_setAction2(autoResp_action_reTx);
[1486]822
[1174]823    //For now, assume our destination is our opposite ID (all traffic is 0 <-> 1)
[1231]824    // and the node 2 is always our relay
[1174]825    destNode = (myID+1)%2;
[1486]826   
[1492]827    if(alternating&&currentAlt){
828        relayNode = 2;
829    }
830    else{
831        relayNode = myID;
832    }
[1490]833
[1492]834//relayNode = 2;
[1486]835   
836//xil_printf("RELAY NODE%d\r\n",relayNode);
[1259]837
838    //Increment the sequence number for this destination
[1486]839    txSequences[destNode] = ( (txSequences[destNode]+1) & 0xFFFF);
[1259]840
841    //Set this packet's remainingTx count to the maximum
842    txBuffer.remainingTx = max_numTransmissions;
843
844    //Construct the new wireless packet's header
845    txBuffer.header.length = length;        //Packet length (payload only)
846    txBuffer.header.pktType = DATAPACKET;   //Packet type DATA
847    txBuffer.header.fullRate = pktFullRate; //Full-rate modulation scheme
848    txBuffer.header.codeRate = pktCodeRate; //Coding rate (ignored for uncoded PHY)
849    txBuffer.header.seqNum = txSequences[destNode]; //Dest node's next seqeunce number
850    txBuffer.header.srcAddr = NODEID_TO_ADDR(myID);         //Source MAC address
851    txBuffer.header.destAddr = NODEID_TO_ADDR(destNode);    //Destination MAC address
852    txBuffer.header.relAddr = NODEID_TO_ADDR(relayNode);    //Relay MAC address
[1486]853
[1174]854   
[1259]855    //Copy the header over to the DATA Tx packet buffer
856    warpmac_prepPhyForXmit(&txBuffer, pktBuf_tx_DATA);
857
[1486]858
859    if(enableStats) stats_numDataTx[destNode][myID][currentAlt]++;
860    currentAlt = (currentAlt+1)%2; 
861
[1259]862    //Packet is ready for transmission
[1174]863    if(warpmac_carrierSense()){
[1259]864        //Medium is idle; transmit right away
[1231]865        warpmac_startPhyXmit(pktBuf_tx_DATA);
[1461]866       
867        ////CRH
[1467]868        //              xil_printf("****TRANSMIT****\r\n");
869        //              unsigned int test = 64;
870        //              unsigned int testIndex;
[1461]871                       
[1467]872        //              for(testIndex=0;testIndex<test;testIndex++){
873        //                  xil_printf("%x ",0xFF&(*((char *)warpphy_getBuffAddr(pktBuf_tx_DATA)+NUM_HEADER_BYTES+testIndex)));
874        //              }
875        //              xil_printf("****TRANSMIT****\r\n");
[1461]876    ////CRH
[1231]877
[1174]878        //Wait for it to finish and enable the receiver
879        warpmac_finishPhyXmit();
[1279]880        warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA_SWAPPED);
[1231]881
[1174]882        //Start a timeout timer
[1186]883        warpmac_setTimer(TIMEOUT_TIMER);
[1231]884
885        //Decrement the remaining resent counter
[1259]886        if(txBuffer.remainingTx > 0){
887            txBuffer.remainingTx = txBuffer.remainingTx - 1;
888        }
[1174]889    }
[1486]890   
[1174]891    else{
[1259]892        //Medium was busy in the last DIFS period; wait a random backoff before transmitting
[1186]893        warpmac_setTimer(BACKOFF_TIMER);
[1174]894    }
895   
[1486]896    if(enableStats){
897    controllerGroup.controllerID = 0;
898    controllerGroup.controllerGrp = 0;
899    controllerGroup.access = 1;
900
901    rtObserve.structID = STRUCTID_RTOBSERVE;
902    rtObserve.nodeID = myID;
903    rtObserve.sequenceNumber = txBuffer.header.seqNum;
904    rtObserve.pktType = txBuffer.header.pktType;
905    rtObserve.srcNode = txBuffer.header.srcAddr;
906    rtObserve.destNode = txBuffer.header.destAddr;
907    rtObserve.relNode = txBuffer.header.relAddr;
908    rtObserve.rssi = 0xFFFF;
909    rtObserve.gain = 0xFFFF;
910    rtObserve.state=0xFF;
911    rtObserve.timeStampHigh = (unsigned short)((timeStamp>>32)&0xFFFF); 
912    rtObserve.timeStampLow = (unsigned int)(timeStamp&0xFFFFFFFF);
913    txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetRTObserve) + sizeof(warpnetControllerGroup);
914   
915    int pktBuf_payloadAddr = warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
916    memcpy((void *)pktBuf_payloadAddr, &(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
917    memcpy((void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader), &controllerGroup, sizeof(warpnetControllerGroup));
918    memcpy((void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader)+sizeof(warpnetControllerGroup), &(rtObserve), sizeof(warpnetRTObserve));
919   
920
921
922    //xil_printf("%d, %d, %d, %d\r\n" ,rtObserve.sequenceNumber,rtObserve.srcNode ,rtObserve.destNode ,rtObserve.relNode );
923               
924    warpmac_prepPktToNetwork((void *)pktBuf_payloadAddr, txEthPktHeader.pktLength);
925    warpmac_startPktToNetwork(txEthPktHeader.pktLength);
926   
927   
928   
929   
930    }
931   
932   
[1174]933    return;
934}
935
936///@brief Callback for the reception of bad wireless headers
937///
938///@param packet Pointer to received Macframe
939void phyRx_badHeader_callback() {
[1486]940
[1174]941   
942    userIOBoard_LEDs = userIOBoard_LEDs==0x80 ? 0x01 : (userIOBoard_LEDs << 1);
943
[1486]944    if(enableStats) stats_numBadHeaderRx++;
[1461]945
[1486]946   
[1244]947    if(agcPrintMode)
948    {
949        agcGains = ofdm_AGC_GetGains();
950        pktDet_rssi = ofdm_txrx_mimo_ReadReg_Rx_PktDet_midPktRSSI_antA();
951        xil_printf("(bad)\tAGC Gains: %d %d\t%d %d\t", agcGains&0x3, (agcGains>>2)&0x1F, (agcGains>>8)&0x3, (agcGains>>10)&0x1F);
952        //      xil_printf("AGC Thresholds: %d / %d / %d\t", (0xFFFFFF00 | agc_coarseThresh_1), (0xFFFFFF00 | agc_coarseThresh_2), (0xFFFFFF00 | agc_coarseThresh_3) );
953        xil_printf("RSSI (ant A): %d\r\n", pktDet_rssi);
954    }
955
[1253]956   
[1174]957    return;
958}
959
960///@brief Callback for the reception of good wireless headers
961///
962///This function then polls the PHY to determine if the entire packet passes checksum
963///thereby triggering the transmission of the ACK and the transmission of the received
964///data over Ethernet.
965///@param packet Pointer to received Macframe
[1490]966int phyRx_goodHeader_callback(Macframe* packet){
967
968int manualClear = 0;
969
[1492]970
971
[1490]972warpmac_setDebugGPIO(0x1,0x1);
[1279]973        unsigned int currPhaseInc;
[1461]974    unsigned char state=PHYRXSTATUS_INCOMPLETE;
[1486]975    unsigned char srcNode,dstNode,relNode,relMode;
[1174]976    unsigned char shouldSend = 0;
[1486]977    warpnetRTObserve rtObserve;
978    warpnetControllerGroup controllerGroup;
979    XTime timeStamp;
[1231]980    int i;
[1486]981    shouldSend = 0;
[1174]982   
[1486]983    XTime_GetTime(&timeStamp);
984   
985    controllerGroup.controllerID = 0;
986    controllerGroup.controllerGrp = 0;
987    controllerGroup.access = 1;
988   
[1259]989    //Extract the source node ID from the packet's source address
[1231]990    srcNode = ADDR_TO_NODEID(packet->header.srcAddr);
[1486]991    relNode = ADDR_TO_NODEID(packet->header.relAddr);
992    dstNode = ADDR_TO_NODEID(packet->header.destAddr);
993
994    rtObserve.structID = STRUCTID_RTOBSERVE;
995    rtObserve.nodeID = myID;
996    rtObserve.sequenceNumber = packet->header.seqNum;
997    rtObserve.pktType = packet->header.pktType;
998    rtObserve.srcNode = srcNode;
999    rtObserve.destNode = dstNode;
1000    rtObserve.relNode = relNode;
1001    rtObserve.rssi = ofdm_txrx_mimo_ReadReg_Rx_PktDet_midPktRSSI_antA();
1002    rtObserve.gain = warpphy_returnGainsDB();
1003    rtObserve.timeStampHigh = (unsigned short)((timeStamp>>32)&0xFFFF); 
1004    rtObserve.timeStampLow = (unsigned int)(timeStamp&0xFFFFFFFF);
1005    txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetRTObserve) + sizeof(warpnetControllerGroup);
[1174]1006   
[1486]1007
1008   
1009    int pktBuf_payloadAddr = warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
1010    memcpy((void *)pktBuf_payloadAddr, &(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
1011    memcpy((void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader), &controllerGroup, sizeof(warpnetControllerGroup));
1012    memcpy((void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader)+sizeof(warpnetControllerGroup), &(rtObserve), sizeof(warpnetRTObserve));
1013                       
[1490]1014
[1486]1015   
1016    if(relNode==2){
1017        relMode = 1;
1018    }
1019    else{
1020        relMode = 0;
1021    }
1022   
1023    if(enableStats) stats_sumGains[myID][srcNode][relMode] += warpphy_returnGainsDB();
1024    //xil_printf("GAINS = %d\r\n",warpphy_returnGainsDB());
1025    if(enableStats) stats_sumPacketsRx[myID][srcNode][relMode]++;
1026    if(enableStats) stats_sumRSSI[myID][srcNode][relMode]+=ofdm_txrx_mimo_ReadReg_Rx_PktDet_midPktRSSI_antA();
1027   
[1259]1028    //Debug-only: print AGC values for this packet
1029    if(agcPrintMode)
[1244]1030    {
1031        agcGains = ofdm_AGC_GetGains();
1032        pktDet_rssi = ofdm_txrx_mimo_ReadReg_Rx_PktDet_midPktRSSI_antA();
1033        xil_printf("(good)\tAGC Gains: %d %d\t%d %d\t", agcGains&0x3, (agcGains>>2)&0x1F, (agcGains>>8)&0x3, (agcGains>>10)&0x1F);
1034        xil_printf("RSSI (ant A): %d\r\n", pktDet_rssi);
1035    }
1036   
[1174]1037    //Rotate the ring of LEDs clockwise
1038    userIOBoard_LEDs = userIOBoard_LEDs==0x1 ? 0x80 : (userIOBoard_LEDs >> 1);
1039   
[1231]1040    //Print the header (debug only- completely ruins actual performance)
1041#if 0
[1235]1042    xil_printf("Rx Header: ");
[1231]1043    for(i=0; i<24; i++)
1044    {
1045        xil_printf("%d.",*((unsigned char*)&(packet->header) + i));
1046    }
1047    xil_printf("\r\n");
1048#endif
[1259]1049
1050    //If packet is from self, it was (hopefully) transmitted by the relay
1051    // Count this as a retransmission
1052    if(packet->header.srcAddr == ( NODEID_TO_ADDR(myID)) ) {
1053        switch(packet->header.pktType){
1054            case DATAPACKET:
1055                warpmac_clearTimer(TIMEOUT_TIMER);
1056                warpmac_clearTimer(BACKOFF_TIMER);
1057                warpmac_finishPhyRecv();
1058                warpmac_setTimer(TIMEOUT_TIMER);
[1261]1059                if(txBuffer.remainingTx > 0){
1060                    txBuffer.remainingTx = txBuffer.remainingTx - 1;                   
1061                }
1062            break;
1063
[1259]1064            default:
[1261]1065                //This should never, ever happen...
1066            break;
[1259]1067        }
1068
[1486]1069        //return;
[1244]1070    }
1071   
[1174]1072    //If the packet is addressed to this node
[1231]1073    if(packet->header.destAddr == ( NODEID_TO_ADDR(myID)) ) {
[1486]1074
[1174]1075        switch(packet->header.pktType){
1076            case DATAPACKET:
1077               
1078                if((packet->header.length)>1400){
1079                    updateLCD();
1080                }
[1259]1081
[1231]1082                state = warpmac_finishPhyRecv();
[1174]1083               
[1461]1084                if(state&PHYRXSTATUS_GOOD){
[1231]1085                    //Go, go autoResponder ACK!
[1492]1086                    warpmac_incrementLEDHigh();
[1174]1087                   
[1486]1088                   
[1266]1089                    //Check if the last received seq number for this partner node matches this received pkt
1090                    // If not, record the new number and allow the pkt to be forwarded over the wire
1091                    if(ignoreSeqNums || ( (srcNode<MAX_NUMNODES) && (rxSequences[srcNode] != (packet->header.seqNum))) ){
1092                        rxSequences[srcNode] = (packet->header.seqNum);
[1486]1093                        //CRH - NACK CHARACTERIZATION
1094                            if(enableStats) stats_numDataRx[packet->header.destAddr][packet->header.srcAddr][relMode]++;
1095                        //CHR
1096                        //shouldSend = 1;
[1266]1097                    }
1098                   
[1492]1099
[1174]1100                   
[1469]1101                    ////
[1486]1102                    //warp_userioboard_buzzer_set(PERHIGH, DUTYHIGH);
1103                    //warp_userioboard_set_buzzer_en(1&buzzerEnable);
1104                    //warpmac_setTimer(BUZZER_TIMER);
[1469]1105                    ////
1106                   
[1174]1107                    //Update the right-hex display with the current resend count for the received pkt
[1231]1108                    warpmac_leftHex(0xF & (packet->header.seqNum));
[1174]1109                   
1110                    //Starts the DMA transfer of the payload into the EMAC
[1231]1111                    if(shouldSend)
1112                    {
[1467]1113
[1461]1114                        warpmac_prepPktToNetwork((void *)warpphy_getBuffAddr(pktBuf_rx)+NUM_HEADER_BYTES, (packet->header.length));
1115                       
1116                       
[1467]1117                    //  xil_printf("****RECEIVE**\r\n");
1118                    //  unsigned int test = 64;
1119                    //  unsigned int testIndex;
[1461]1120                       
[1467]1121                    //  for(testIndex=0;testIndex<test;testIndex++){
1122                    //      xil_printf("%x ",0xFF&(*((char *)warpphy_getBuffAddr(pktBuf_rx)+NUM_HEADER_BYTES+testIndex)));
1123                    //  }
1124                    //  xil_printf("****RECEIVE****\r\n");
[1461]1125                       
1126                        warpmac_finishPhyXmit();//? needed?
1127                        warpmac_startPktToNetwork(packet->header.length);
1128                       
[1259]1129
[1461]1130
[1486]1131                       
[1231]1132                    }
[1174]1133                   
1134                }
1135               
[1461]1136                if(state&PHYRXSTATUS_BAD){
[1492]1137                warpmac_incrementLEDLow();
[1231]1138                    //Go, go autoReponder NACK!
[1461]1139                    //CRH - NACK CHARACTERIZATION
[1486]1140                    if(enableStats) stats_numNACKTx[packet->header.srcAddr][myID][relMode]++;
[1461]1141                    //CHR
[1469]1142                   
1143                    ////
[1492]1144
[1486]1145                    //warp_userioboard_buzzer_set(PERLOW, DUTYLOW);
1146                    //warp_userioboard_set_buzzer_en(1&buzzerEnable);
1147                    //warpmac_setTimer(BUZZER_TIMER);
[1469]1148                    ////
[1231]1149
[1486]1150
[1174]1151                   
[1486]1152                   
[1174]1153                    //Rotate the ring of LEDs counter-clockwise
1154                    userIOBoard_LEDs = userIOBoard_LEDs==0x80 ? 0x01 : (userIOBoard_LEDs << 1);
[1486]1155                   
[1174]1156                }
[1259]1157           
1158            break;//END DATAPACKET
[1174]1159               
1160            case ACKPACKET:
[1259]1161                pktCount_good++;
1162
[1486]1163
[1259]1164                //Clear the timeout timer, set when we transmitted the data packet
[1231]1165                warpmac_clearTimer(TIMEOUT_TIMER);
[1259]1166
1167                //Clear the backoff timer; this handles the case of receiving an ACK for a forwarded DATA packet
1168                warpmac_clearTimer(BACKOFF_TIMER);
1169
1170                //Clear the remaining transmit count to assure this packet won't be re-transmitted
1171                txBuffer.remainingTx = 0;
1172
1173                //Start a backoff, to gaurantee a random time before attempting to transmit again
[1231]1174                warpmac_setTimer(BACKOFF_TIMER);
[1259]1175
1176            break;//END ACKPACKET
[1174]1177               
1178            case NACKPACKET:
[1486]1179               
1180                if(warpmac_inTimeout())
1181                {
[1492]1182
[1461]1183                //CRH - NACK CHARACTERIZATION
[1486]1184                if(enableStats) stats_numNACKRx[packet->header.destAddr][packet->header.srcAddr][relMode]++;
[1461]1185                //CHR
[1486]1186               
[1266]1187                    //Go, go autoResponder DATA reTx (if it's still enabled)!
[1231]1188
[1259]1189
[1486]1190
[1266]1191                    //Clear the timeout timer, set when we transmitted the data packet
1192                    warpmac_clearTimer(TIMEOUT_TIMER);
[1244]1193
[1266]1194                    if(txBuffer.remainingTx == 0)
1195                    {
1196                        //No more re-transmits; start a backoff, to gaurantee a random time before attempting to transmit a new data packet
1197                        warpmac_setTimer(BACKOFF_TIMER);
1198                    }
1199                    else if(txBuffer.remainingTx == 1)
1200                    {
1201                        //Decrement the remaining transmit count
1202                        txBuffer.remainingTx = txBuffer.remainingTx - 1;
1203                       
1204                        //Disable the autoResponder for data re-transmissions (it already started its last transmission)
1205                        autoResp_action_reTx = 0;
1206                        mimo_ofdmTxRx_setAction2(autoResp_action_reTx);
[1259]1207
[1266]1208                        //Wait for the transmission to finish the autoRepsonse trigger re-trasnmit
1209                        warpmac_finishPhyXmit();
[1261]1210
[1266]1211                        //Start a timeout, waiting for a ACK/NACK
1212                        warpmac_setTimer(TIMEOUT_TIMER);
[1263]1213
[1486]1214                       
[1266]1215                    }
1216                    else//remainingTx > 1
1217                    {
1218                        //Decrement the remaining transmit count
1219                        txBuffer.remainingTx = txBuffer.remainingTx - 1;
1220                       
1221                        //Wait for the transmission to finish the autoRepsonse trigger re-trasnmit
1222                        warpmac_finishPhyXmit();
1223                       
1224                        //Start a timeout, waiting for a ACK/NACK
1225                        warpmac_setTimer(TIMEOUT_TIMER);
1226
[1486]1227                       
[1266]1228                    }
[1174]1229                }
[1266]1230                else if(warpmac_inBackoff())
[1261]1231                {
[1266]1232                    //Covers case where we missed a NACK and missed the relay's re-transmission but heard the terminal NACK
1233                    warpmac_clearTimer(TIMEOUT_TIMER);
1234                    warpmac_clearTimer(BACKOFF_TIMER);
1235                    if(txBuffer.remainingTx > 0)
1236                    {
1237                        txBuffer.remainingTx = txBuffer.remainingTx - 1;
1238                    }
1239                    warpmac_setTimer(BACKOFF_TIMER);
[1261]1240                }
[1266]1241                else
1242                {
[1469]1243                        //warp_userioboard_set_buzzer_en(1);
[1266]1244                }
[1259]1245            break;//END NACKPACKET
[1231]1246        }
[1259]1247
[1486]1248        //return;
[1259]1249    }//END dstAddr == self
[1231]1250
1251    //Relay address matches this node
1252    if(packet->header.relAddr == ( NODEID_TO_ADDR(myID)) ) {
1253
1254        switch(packet->header.pktType){
1255            //If received packet is data
1256            case DATAPACKET:
[1490]1257           
1258//              warpmac_setDebugGPIO(0xF);
1259
1260warpmac_setDebugGPIO(0x4,0x4);
1261
[1231]1262                state = warpmac_finishPhyRecv();
[1490]1263//                  warpmac_setDebugGPIO(0x0); 
1264   
1265                if((state&PHYRXSTATUS_GOOD)&&allowRelay){
[1492]1266warpmac_incrementLEDHigh();
[1490]1267           
[1492]1268//      if(enableStats) stats_numDataRx[myID][packet->header.srcAddr][relMode]++;
[1259]1269                    //We can cooperate on this packet
[1231]1270                    relayMode = 1;
[1267]1271                   
[1259]1272                    //Define and enable the cooperative autoResponse transmitter
1273                    //Flag A will already be set (that actor is always enabled)
[1279]1274                   
[1486]1275
[1279]1276                        //autoResp_action_coopTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_rx, PHY_AUTORESPONSE_ACT_USE_PRECFO, autoRespDelay_AFTx, (REQ_RLY_ME | REQ_NACK | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT | PHY_AUTORESPONSE_REQ_FLAGA));
1277                        autoResp_action_coopTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_AF, 0, autoRespDelay_AFTx, (REQ_RLY_ME | REQ_NACK | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT | PHY_AUTORESPONSE_REQ_FLAGA));
1278                        mimo_ofdmTxRx_setAction4(autoResp_action_coopTx);
[1486]1279
1280
[1259]1281                   
[1235]1282                    //AF recording must be disabled *after* the good pkt interrupt goes high
1283                    // Doing it before will prevent the AF system from knowing when the incoming packet actually stopped
[1490]1284       
[1259]1285                    warpphy_AFrecordEnable(0);
1286                   
1287                    //Increment the Rx packet buffer, to preserve the received data packet
1288                    pktBuf_rx_ind = ((pktBuf_rx_ind + 1) % NUM_RX_PKTBUFS);
1289                    pktBuf_rx = rxPktBufs[pktBuf_rx_ind];
[1267]1290                   
1291                    //warpphy_setBuffs(pktBuf_tx_DATA, pktBuf_rx);
[1461]1292                    warpmac_setRxBuffers(&rxBuffer, pktBuf_rx);
[1267]1293                       
[1490]1294                   
1295                    warpphy_clearRxPktStatus();
1296                    manualClear = 1;
1297                   
[1267]1298                    relayDestID = ADDR_TO_NODEID(packet->header.destAddr);
1299                    relayLen = packet->header.length;
[1259]1300                    //Finally, start a timeout, waiting for a ACK/NACK
[1267]1301                    warpmac_clearTimer(TIMEOUT_TIMER);
[1231]1302                    warpmac_setTimer(TIMEOUT_TIMER);
[1279]1303                   
[1471]1304                    ////
[1486]1305                //warp_userioboard_buzzer_set(PERHIGH, DUTYHIGH);
1306                //warp_userioboard_set_buzzer_en(1&buzzerEnable);
1307                //warpmac_setTimer(BUZZER_TIMER);
[1471]1308                    ////
1309                   
[1490]1310                    return;
[1279]1311                    //DEBUG print
[1490]1312
[1231]1313                }
1314
[1461]1315                if(state&PHYRXSTATUS_BAD){
[1492]1316                warpmac_incrementLEDLow();
[1486]1317                                    ////
1318                //warp_userioboard_buzzer_set(PERLOW, DUTYLOW);
1319                //warp_userioboard_set_buzzer_en(1&buzzerEnable);
1320                //warpmac_setTimer(BUZZER_TIMER);
[1492]1321
[1486]1322                    ////
[1259]1323                    //Let the timeout handler reset things (like restarting AF capture, disabling coop autoResponse, etc.
[1231]1324                }
[1259]1325           
[1231]1326                   
[1259]1327            break;//END DATAPACKET
[1231]1328
1329            case NACKPACKET:
[1486]1330                if(enableStats) stats_numNACKRx[myID][packet->header.srcAddr][relMode]++;
1331           
1332
1333               
1334                                    ////
1335                    //warp_userioboard_buzzer_set(PERLOW, DUTYLOW);
1336                    //warp_userioboard_set_buzzer_en(1&buzzerEnable);
1337                    //warpmac_setTimer(BUZZER_TIMER);
[1492]1338
[1486]1339                    ////
1340                   
[1259]1341                if(relayMode) {
[1486]1342
[1492]1343
[1267]1344               
[1486]1345                    if(enableStats) if(enableStats) stats_numDataTx[packet->header.srcAddr][myID][relMode]++;
1346//CRH ADDME                 if(enableStats) stats_numDataTx[][]++;
[1279]1347                   
[1486]1348                   
1349
[1259]1350                    //Go, go autoRepsonder AF Tx!
[1486]1351
[1267]1352                   
[1471]1353                   
[1279]1354//                  warpmac_setDebugGPIO(0xF);
[1259]1355
1356                    //Clear the timeout (started when we recevied the DATA packet)
[1231]1357                    warpmac_clearTimer(TIMEOUT_TIMER);
1358                   
[1259]1359                    //Wait for the autoResponse transmission to finish
[1231]1360                    warpmac_finishPhyXmit();
[1267]1361
[1279]1362//                  warpmac_setDebugGPIO(0x0);
[1259]1363                    //Restart capturing the AF waveform, now that we've sent the good one we had
[1490]1364                    //warpmac_setDebugGPIO(0xF);
[1231]1365                    warpphy_AFrecordEnable(1);
[1259]1366
1367                    //Disable the cooperative autoResponse transmitter
1368                    autoResp_action_coopTx = 0;
1369                    mimo_ofdmTxRx_setAction4(autoResp_action_coopTx);
[1267]1370                   
1371       
[1486]1372
[1267]1373                   
[1486]1374                   
[1231]1375                    relayMode = 0;
1376                }
[1486]1377                else{
1378               
1379                }
[1259]1380            break;//END NACKPACKET
[1231]1381
1382            case ACKPACKET:
[1259]1383                //Clear the timeout (started when we recevied the DATA packet)
[1231]1384                warpmac_clearTimer(TIMEOUT_TIMER);
[1259]1385
1386                //Restart capturing the AF waveform, now that we've sent the good one we had
[1490]1387                //warpmac_setDebugGPIO(0xF);
[1231]1388                warpphy_AFrecordEnable(1);
[1259]1389               
1390                //Disable the cooperative autoResponse transmitter
1391                autoResp_action_coopTx = 0;
1392                mimo_ofdmTxRx_setAction4(autoResp_action_coopTx);
1393               
[1267]1394   
[1486]1395
[1267]1396       
1397               
1398               
[1259]1399                relayMode = 0;
1400            break;//END ACKPACKET
[1174]1401        }
[1490]1402    //  return;
[1174]1403    }
[1486]1404   
1405   
1406   
1407    if(enableStats){
1408    //  xil_printf("%d,%d,%d,%d\r\n",rtObserve.sequenceNumber,rtObserve.srcNode,rtObserve.destNode,rtObserve.relNode);
1409   
1410               
1411                unsigned char* stateAddr = (void *)pktBuf_payloadAddr+sizeof(warpnetEthernetPktHeader)+sizeof(warpnetControllerGroup) + 8;
1412                *stateAddr = warpmac_finishPhyRecv();
1413               
1414                warpmac_prepPktToNetwork((void *)pktBuf_payloadAddr, txEthPktHeader.pktLength);
1415                warpmac_startPktToNetwork(txEthPktHeader.pktLength);
[1492]1416
[1486]1417    }
1418   
[1490]1419    return manualClear;
1420
[1174]1421}
1422
1423///@brief Main function
1424///
1425///This function configures MAC parameters, enables the underlying frameworks, and then loops forever.
1426int main(){     
1427   
1428    //Initialize global variables
[1259]1429    cfoVar = 38;
[1174]1430    currentAnt = 0;
[1259]1431    chan = 4;
[1244]1432
1433    agcPrintMode = 0;
[1461]1434    randomData_Mode = 0;
[1174]1435   
1436    pktCount_good = 0;
1437    pktCount_bad = 0;
[1231]1438
1439    //Not a relay by default
1440    relayMode = 0;
[1244]1441
[1467]1442   
[1259]1443    debug_sisoMode = 0;
[1244]1444    ignoreSeqNums = 0;
1445   
[1486]1446       
[1471]1447    txPower = 0x3f;
[1467]1448   
[1231]1449    //Set the full-rate modulation to QPSK by default
[1467]1450//  pktFullRate = HDR_FULLRATE_QPSK;
1451    pktFullRate = HDR_FULLRATE_QAM_16;
[1174]1452   
1453    //Set the payload coding rate to NONE by default
1454    //Note: Reference Design 12 PHY does not provide channel coding
1455    pktCodeRate = CODE_RATE_NONE;
1456   
1457    //Initialize the framework
1458    warpmac_init();
[1259]1459    max_numTransmissions = 2;
1460    warpmac_setMaxResend(max_numTransmissions);
[1174]1461    warpmac_setMaxCW(5);
[1231]1462
1463    //Select single-antenna Alamouti mode for both Tx and Rx
[1244]1464    if(debug_sisoMode)
[1253]1465    //  warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA);
1466    warpphy_setAntennaMode(TX_ANTMODE_ALAMOUTI_2ANT, RX_ANTMODE_ALAMOUTI_ANTA);
[1244]1467    else
1468        warpphy_setAntennaMode(TX_ANTMODE_ALAMOUTI_ANTA, RX_ANTMODE_ALAMOUTI_ANTA);
[1231]1469
[1279]1470    warpmac_setTimeout(140); //100
[1174]1471    warpmac_setSlotTime(22); //9 20
1472   
1473    //Read Dip Switch value from FPGA board.
1474    //This value will be used as an index into the routing table for other nodes
[1231]1475    myID = (unsigned short int)warpmac_getMyId();
[1461]1476    warpmac_leftHex(myID);
[1259]1477    //Define the available Rx pkt buffers (1 and 2 act as Ping and Pong for now)
1478    rxPktBufs[0] = 1;
1479    rxPktBufs[1] = 2;
1480    pktBuf_rx_ind = 0;
1481
1482    pktBuf_rx = rxPktBufs[pktBuf_rx_ind];
[1486]1483    pktBuf_rx_emac = 3;
1484    pktBuf_tx_DATA = 4;
[1259]1485    pktBuf_tx_ACK = 29;
1486    pktBuf_tx_NACK = 30;
[1231]1487    pktBuf_tx_AF = 31;
[1261]1488
[1244]1489    cfoDly = 16;
[1279]1490    antB_preambleShift = 3;
[1263]1491
[1492]1492    autoRespDelay_NACKTx = 2; //100
[1259]1493    autoRespDelay_AFTx = 2;
[1231]1494    autoRespDelay_ReTx = 2;
[1266]1495    autoRespDelay_ACKTx = 0;
[1174]1496   
[1261]1497    rx_correThresh = 1400;
[1244]1498   
[1486]1499
[1261]1500   
[1174]1501    //Rx buffer is where the EMAC will DMA Wireless payloads from
[1461]1502    warpmac_setRxBuffers(&rxBuffer, pktBuf_rx);
[1174]1503    //Tx buffer is where the EMAC will DMA Ethernet payloads to
[1461]1504    warpmac_setPHYTxBuffer(pktBuf_tx_DATA);
[1486]1505    warpmac_setEMACRxBuffer(pktBuf_rx_emac);//VERY VERY IMPORTANT
[1174]1506   
1507    //Copy this node's MAC address into the Tx buffer's source address field
[1231]1508    txBuffer.header.srcAddr = (unsigned short int)( NODEID_TO_ADDR(myID) );
[1174]1509   
1510    //Register callbacks
[1461]1511
[1174]1512   
[1461]1513    warpmac_setCallback(EVENT_PHYGOODHEADER, (void *)phyRx_goodHeader_callback);
1514    warpmac_setCallback(EVENT_PHYBADHEADER, (void *)phyRx_badHeader_callback);
1515    warpmac_setCallback(EVENT_MGMTPKT, (void *)mgmtFromNetworkLayer_callback);
1516    warpmac_setCallback(EVENT_DATAFROMNETWORK, (void *)dataFromNetworkLayer_callback);
1517    warpmac_setCallback(EVENT_UARTRX, (void *)uartRecv_callback);
1518    warpmac_setCallback(EVENT_TIMER, (void *)timer_callback);
1519   
1520    warpmac_setCallback(EVENT_UPBUTTON, (void *)up);
1521    warpmac_setCallback(EVENT_MIDDLEBUTTON, (void *)middle);
1522    warpmac_setCallback(EVENT_LEFTBUTTON, (void *)left);
1523    warpmac_setCallback(EVENT_RIGHTBUTTON, (void *)right);
1524   
[1266]1525    //Configure a buzzer tone, to be enabled on odd error conditions
[1469]1526//  warp_userioboard_buzzer_set(40000, 13107);
[1231]1527
[1174]1528    userIOBoard_LEDs = 1;
1529    //Initialize the LCD for slot 1 (i.e. don't flip the image) and non-inverted colors
1530    warp_userioboard_lcd_init(1, 0);
1531    warp_userioboard_set_lcd_charbuf(1);
1532   
1533    //Print some static lines to the user I/O board LCD
1534    //snprintf(charsToPrint, 16, " Ref Design v12 ", pktCount_bad);
[1461]1535    warp_userio_lcd_printline("RefDesign v14", 16, 1, 1);
[1174]1536    //snprintf(charsToPrint, 16, "  Rx Pkt Counts", pktCount_bad);
1537    warp_userio_lcd_printline("  Rx Pkt Counts ", 16, 3, 1);
1538   
1539    //Set the user I/O board LEDs
1540    warp_userioboard_set_leds(userIOBoard_LEDs);
1541   
1542    //Set the default center frequency
1543    warpphy_setChannel(GHZ_2, chan);
1544   
1545    //Enable carrier sensing
[1461]1546    warpmac_setCSMA(1);
[1244]1547
[1231]1548/*****************************************/
1549/******** START autoResponse setup *******/
1550/*****************************************/
1551
1552    /*****************************************/
1553    //Header Match Unit Setup
1554    /*****************************************/
1555    // 0: Destination address == self
1556    // 1: Relay address == self
1557    // 2: Packet type == DATAPACKET
1558    // 3: Packet type == NACK
[1174]1559   
[1231]1560    //Match condition 0: received header's destination address is me
1561    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_DSTADDR, 2, htons(NODEID_TO_ADDR(myID)));
1562    mimo_ofdmTxRx_setMatch0(autoResp_matchCond);
1563
1564    //Match condition 1: received header's relay address is me
1565    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_RLYADDR, 2, htons(NODEID_TO_ADDR(myID)));
1566    mimo_ofdmTxRx_setMatch1(autoResp_matchCond);
1567   
1568    //Match condition 2: packet type is data
1569    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_TYPE, 1, DATAPACKET);
1570    mimo_ofdmTxRx_setMatch2(autoResp_matchCond);
1571   
1572    //Match condition 3: packet type is NACK
1573    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_TYPE, 1, NACKPACKET);
1574    mimo_ofdmTxRx_setMatch3(autoResp_matchCond);
1575
1576    /*****************************************/
1577    //Header translation setup
1578    /*****************************************/
1579   
1580    //Configure the header translator to use the Rx pkt's src address as the outgoing pkt's dst address
1581    // Addresses are two bytes, so two entries in the header translator need to be overridden
1582    // Except for these bytes, the ACK/NACK pktBuf's contents will be sent unaltered
1583    // Macro is PHY_HEADERTRANSLATE_SET(templatePktBuf, byteAddrToOverwrite, srcPktBuf, srcByteAddr)
1584    PHY_HEADERTRANSLATE_SET(pktBuf_tx_ACK, (PKTHEADER_INDX_DSTADDR+0), pktBuf_rx, (PKTHEADER_INDX_SRCADDR+0));
1585    PHY_HEADERTRANSLATE_SET(pktBuf_tx_ACK, (PKTHEADER_INDX_DSTADDR+1), pktBuf_rx, (PKTHEADER_INDX_SRCADDR+1));
1586    PHY_HEADERTRANSLATE_SET(pktBuf_tx_ACK, (PKTHEADER_INDX_RLYADDR+0), pktBuf_rx, (PKTHEADER_INDX_RLYADDR+0));
1587    PHY_HEADERTRANSLATE_SET(pktBuf_tx_ACK, (PKTHEADER_INDX_RLYADDR+1), pktBuf_rx, (PKTHEADER_INDX_RLYADDR+1));
1588    PHY_HEADERTRANSLATE_SET(pktBuf_tx_NACK, (PKTHEADER_INDX_DSTADDR+0), pktBuf_rx, (PKTHEADER_INDX_SRCADDR+0));
1589    PHY_HEADERTRANSLATE_SET(pktBuf_tx_NACK, (PKTHEADER_INDX_DSTADDR+1), pktBuf_rx, (PKTHEADER_INDX_SRCADDR+1));
1590    PHY_HEADERTRANSLATE_SET(pktBuf_tx_NACK, (PKTHEADER_INDX_RLYADDR+0), pktBuf_rx, (PKTHEADER_INDX_RLYADDR+0));
1591    PHY_HEADERTRANSLATE_SET(pktBuf_tx_NACK, (PKTHEADER_INDX_RLYADDR+1), pktBuf_rx, (PKTHEADER_INDX_RLYADDR+1));
1592
1593    //Create a template ACK packet
1594    templatePkt.header.fullRate = pktFullRate;
1595    templatePkt.header.codeRate = pktCodeRate;
1596    templatePkt.header.length = 0;
1597    templatePkt.header.srcAddr = (unsigned short)(NODEID_TO_ADDR(myID));
1598    templatePkt.header.pktType = ACKPACKET;
1599   
1600    //Copy the header down to the PHY's packet buffer
1601    // This doesn't actually send anything; the autoResponse system will use this template when sending ACKs
1602    warpmac_prepPhyForXmit(&templatePkt, pktBuf_tx_ACK);
1603
1604    //Create a template NACK packet
1605    templatePkt.header.fullRate = pktFullRate;
1606    templatePkt.header.codeRate = pktCodeRate;
1607    templatePkt.header.length = 0;
1608    templatePkt.header.srcAddr = (unsigned short)(NODEID_TO_ADDR(myID));
1609    templatePkt.header.pktType = NACKPACKET;
1610   
1611    //Copy the header down to the PHY's packet buffer
1612    // This doesn't actually send anything; the autoResponse system will use this template when sending ACKs
1613    warpmac_prepPhyForXmit(&templatePkt, pktBuf_tx_NACK);
1614   
1615    /*****************************************/
1616    //Actions setup
1617    // Action definitions come last; bad things might happen if an action is enabled before the template pkt is ready
1618    /*****************************************/
1619    //Actors:
1620    // 0: ACK transmission for good header, good payload DATA
1621    // 1: NACK transmission for good header, bad payload DATA
1622    // 2: DATA retransmisson from source
1623    // 3: SetFlagA at relay
1624    // 4: AF retransmission from relay
[1235]1625   
[1279]1626    autoResp_action = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_ACK, PHY_AUTORESPONSE_ACT_TRANS_HDR, autoRespDelay_ACKTx, (REQ_DST_ME | REQ_DATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
[1492]1627    mimo_ofdmTxRx_setAction0(autoResp_action);
1628//  mimo_ofdmTxRx_setAction0(0); //Use this to disable ACKs
[1231]1629   
[1492]1630    autoResp_action = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_NACK, PHY_AUTORESPONSE_ACT_TRANS_HDR, autoRespDelay_NACKTx, (REQ_DST_ME | REQ_DATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_BADPKT));
1631//  autoResp_action = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_NACK, PHY_AUTORESPONSE_ACT_TRANS_HDR, autoRespDelay_NACKTx, (REQ_DST_ME | REQ_DATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT)); //Use for NACKs in place of ACKs
[1231]1632    mimo_ofdmTxRx_setAction1(autoResp_action);
1633   
[1261]1634//  autoResp_action_reTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_DATA, 0, autoRespDelay_ReTx, (REQ_DST_ME | REQ_NACK | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
1635//  mimo_ofdmTxRx_setAction2(autoResp_action_reTx);
[1231]1636   
[1235]1637    autoResp_action = PHY_AUTORESPONSE_ACTION_SETFLAGA_CONFIG((REQ_RLY_ME | REQ_DATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
[1231]1638    mimo_ofdmTxRx_setAction3(autoResp_action);
1639   
[1259]1640//  autoResp_action_coopTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_AF, 0, autoRespDelay_AFTx, (REQ_RLY_ME | REQ_NACK | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT | PHY_AUTORESPONSE_REQ_FLAGA));
[1261]1641//  autoResp_action_coopTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_rx, 0, autoRespDelay_AFTx, (REQ_RLY_ME | REQ_NACK | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT | PHY_AUTORESPONSE_REQ_FLAGA));
1642//  mimo_ofdmTxRx_setAction4(autoResp_action_coopTx);
[1231]1643   
1644/*****************************************/
1645/******** END autoResponse setup *******/
1646/*****************************************/
1647   
1648    //Enable local packet generation (ignoring Ethernet)
[1486]1649    warpmac_setDummyPacketMode(1);
[1231]1650   
1651    //Listen for new packets to send (either from Ethernet or local dummy packets)
1652    warpmac_enableDataFromNetwork();
1653   
[1174]1654    //Set the modulation scheme use for base rate (header) symbols
[1467]1655//  warpmac_setBaseRate(QPSK);
[1279]1656    warpmac_setBaseRate(BPSK);
[1174]1657   
[1253]1658    XTime rand_time;
[1486]1659    XTime_GetTime(&rand_time);
[1253]1660   
1661    //Seed Random Number Generator
1662    srand(myID ^ ((int) rand_time) ^ WarpRadio_v1_RSSIData(RADIO2_ADDR));
1663   
1664   
1665    unsigned int pktBuf_payloadAddr;
1666   
1667   
1668   
1669   
[1493]1670    xil_printf("Reference Design v15.04 DOCMAC\r\n");
[1174]1671    xil_printf("Beginning main loop\r\n");
1672   
[1259]1673   
1674    //////
1675    ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) & ~(COARSE_CFO_EN));
1676    xil_printf("Coarse CFO Disabled\r\n");
1677
[1279]1678    //mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() | BYPASS_CARR_REC, DEFAULT_STATUSBITS);
1679    //xil_printf("Carrier Rec Bypass\r\n");
1680
[1259]1681    //////
[1486]1682    int i,j;
[1259]1683    ////Load Up Random Data into Pkt Buffers 3-28////
1684    for (i=3; i<=28; i++) {
1685        unsigned char* byteLoc = (unsigned char*)warpphy_getBuffAddr(i);
1686        for (j=0; j<2000; j++) {
1687            *(byteLoc+j) = (unsigned char)(rand()&0xFF);
1688        }
1689    }
1690    /////////////////////////////////////////////////
1691   
[1461]1692    //Hard-code which nodes send which Alamouti streams - relay always sense stream B
[1259]1693    if(myID == 0 || myID == 1)
1694        warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA);
1695    else if(myID == 2)
[1279]1696        warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA); //CRH
[1259]1697   
[1486]1698    //if(myID == 0)
1699    //{
[1259]1700    //Be the source
[1486]1701    //  warpmac_startPacketGeneration(1300, 1500); //900,1500
1702    //}
1703   
[1279]1704    respondToNacks = 1;
[1469]1705    buzzerEnable = 0;
[1279]1706   
1707    docPreambleScaling=2480;
1708    docPayloadScaling=9792;
1709    mimo_ofdmTx_setTxScaling(docPreambleScaling,docPayloadScaling);
1710    warpphy_setAntBPreambleShift(antB_preambleShift);
1711   
[1467]1712    warpphy_setTxPower(txPower);
1713   
[1486]1714   
1715    //WARPnet configuration
1716    txEthPktHeader.ethType = WARPNET_ETHTYPE_NODE2SVR;
1717    txEthPktHeader.srcAddr[0]=0x00;
1718    txEthPktHeader.srcAddr[1]=0x50;
1719    txEthPktHeader.srcAddr[2]=0xC2;
1720    txEthPktHeader.srcAddr[3]=0x63;
1721    txEthPktHeader.srcAddr[4]=0x3F;
1722    txEthPktHeader.srcAddr[5]=0x80+myID;
1723    //HARDCODED TO MACBOOK!!
1724    txEthPktHeader.dstAddr[0]=0x00;
1725    txEthPktHeader.dstAddr[1]=0x50;
1726    txEthPktHeader.dstAddr[2]=0xc2;
1727    txEthPktHeader.dstAddr[3]=0x63;
1728    txEthPktHeader.dstAddr[4]=0x3f;
1729    txEthPktHeader.dstAddr[5]=0xef; 
[1492]1730
[1486]1731    sleep(8);
1732    unsigned char ethernetAddr[] = {0x00,0x50,0xC2,0x63,0x3F,0x80+myID};
[1493]1733    warpnet_setMacAddr((void*)&ethernetAddr);
[1486]1734    warpnet_sendGratuitousArp(myID);
[1490]1735
[1486]1736    ///////
1737   
[1492]1738    allowRelay = 0;
1739    alternating = 0;
[1490]1740//  if(myID==0) warpmac_startPacketGeneration(1300, 10000);
[1492]1741
1742warpphy_AFrecordEnable(0);
1743warpphy_AFrecordEnable(1);
[1486]1744   
[1174]1745    while(1){
[1486]1746        warpmac_pollPeripherals();     
[1174]1747    }
1748   
1749    return;
1750}
Note: See TracBrowser for help on using the repository browser.