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
Line 
1/*! \file doc.c
2 \brief Distributed On-Demand Cooperation
3 
4 @version 15
5 @author Chris Hunter and Patrick Murphy
6 
7 
8 */
9#include "warpmac.h"
10#include "warpnet.h"
11#include "warpphy.h"
12#include "docMac.h"
13#include "xparameters.h"
14#include "ofdm_txrx_mimo_regMacros.h"
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"
21#include "radio_controller_ext.h"
22#include "xtime_l.h"
23
24
25
26#define PERLOW  80000
27#define PERHIGH 60000
28#define DUTYLOW 13107
29#define DUTYHIGH 13107
30
31#define htons(A) ((((Xuint16)(A) & 0xff00) >> 8) | (((Xuint16)(A) & 0x00ff) << 8))
32#define MAX_NUMNODES 3
33
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
39#define NUM_RX_PKTBUFS 2
40
41
42
43unsigned char randomData_Mode;
44
45Macframe templatePkt;
46unsigned int autoResp_matchCond;
47unsigned int autoResp_action;
48unsigned int autoResp_action_reTx;
49unsigned int autoResp_action_coopTx;
50unsigned short autoRespDelay_NACKTx, autoRespDelay_AFTx, autoRespDelay_ReTx, autoRespDelay_ACKTx;
51unsigned int docPreambleScaling,docPayloadScaling;
52unsigned int txPower;
53
54unsigned char relayDestID;
55unsigned int relayLen;
56unsigned char alternating;
57unsigned char currentAlt;
58
59XTime startTime;
60XTime stopTime;
61
62unsigned char pktBuf_tx_ACK;
63unsigned char pktBuf_tx_NACK;
64unsigned char pktBuf_tx_DATA;
65unsigned char pktBuf_rx_emac;
66unsigned char pktBuf_tx_AF;
67unsigned char pktBuf_rx;
68unsigned char rxPktBufs[NUM_RX_PKTBUFS];
69unsigned char pktBuf_rx_ind;
70unsigned char respondToNacks;
71
72unsigned char relayMode;
73unsigned short relayMode_lastSrcAddr;
74
75unsigned char enableStats;
76int pktGen_length;
77int pktGen_period;
78unsigned char enablePktGen;
79unsigned char allowRelay;
80
81unsigned short rx_correThresh;
82unsigned char cfoDly;
83unsigned char ignoreSeqNums;
84unsigned char cfoVar;
85unsigned char agcPrintMode;
86unsigned int pktDet_rssi;
87unsigned int agcGains;
88unsigned char antB_preambleShift;
89unsigned char debug_sisoMode;
90unsigned char userIOBoard_LEDs;
91unsigned char charsToPrint[16];
92unsigned int pktCount_good, pktCount_bad;
93
94unsigned short int rxSequences[MAX_NUMNODES];
95unsigned short int txSequences[MAX_NUMNODES];
96
97unsigned char max_numTransmissions;
98
99///Index to the routing table that identifies this node
100unsigned short int myID;
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
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
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
129unsigned char buzzerEnable;
130
131//Define handy macros for MAC packet types
132///ACK/NACK packet types
133#define ACKPACKET 0
134#define NACKPACKET 1
135///Data packet types
136#define DATAPACKET 2
137
138// Aid for Debugging Purposes, if 1 print from Teraterm
139#define PrintDebug 0
140
141warpnetEthernetPktHeader txEthPktHeader;
142
143
144void resetStats(){
145int i,j,k;
146
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    }
159}
160
161stats_numBadHeaderRx=0;
162}
163
164
165///@brief Callback for the depression of the left push button
166///
167///This function is empty by default
168void left(){
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);
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(){
181//  stats_numDataTx=0;
182//  stats_numDataRx=0;
183//  stats_numBadHeaderRx=0;
184//  stats_numNACKTx=0;
185//  stats_numNACKRx=0;
186//  numRelayTx = 0;
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(){
193    buzzerEnable = 1;
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(){
200    buzzerEnable  = 0;
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
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);
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        {
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               
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               
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               
278            case ASCII_6:
279                pktFullRate = HDR_FULLRATE_QAM_64;
280                xil_printf("Tx Full Rate = 64-QAM\r\n");
281                break;
282           
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;
297
298            case ASCII_O:
299                warpphy_set_FFTOffset_Plus();
300                break;
301            case ASCII_o:
302                warpphy_set_FFTOffset_Minus();
303                break;
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;
314            case ASCII_G:
315                txPower++;
316                warpphy_setTxPower(txPower);
317                xil_printf("New Tx Power = 0x%x\r\n",txPower);
318                break;
319            case ASCII_g:
320                txPower--;
321                warpphy_setTxPower(txPower);
322                xil_printf("New Tx Power = 0x%x\r\n",txPower);
323                break;
324            case ASCII_C:
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");
327                break;
328            case ASCII_c:
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");
331                break;
332            case ASCII_A:
333                xil_printf("AF/ReTx enabled\r\n");
334                respondToNacks = 1;
335                break;
336            case ASCII_a:
337                xil_printf("AF/ReTx disabled\r\n");
338                respondToNacks = 0;
339                break;
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
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               
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               
372            case ASCII_x:
373                //warpmac_uhoh();
374                break;
375               
376               
377            case ASCII_S:
378                //warpphy_setAFScalingPlus();
379                break;
380               
381            case ASCII_s:
382                //warpphy_setAFScalingMinus();
383                break;
384           
385            case ASCII_P:
386                warpphy_setPktDetPlus(200);
387                break;
388
389            case ASCII_p:
390                warpphy_setPktDetMinus(200);
391                break;
392               
393            case ASCII_B:
394                //antB_preambleShift++;
395                //warpphy_setAntBPreambleShift(antB_preambleShift);
396                //xil_printf("AntB Preamble Shift: %d\r\n", antB_preambleShift);
397                break;
398               
399            case ASCII_b:
400                //antB_preambleShift--;
401                //warpphy_setAntBPreambleShift(antB_preambleShift);
402                //xil_printf("AntB Preamble Shift: %d\r\n", antB_preambleShift);
403                break;
404               
405            case ASCII_R:
406                autoRespDelay_AFTx++;
407                autoRespDelay_ReTx++;
408                xil_printf("autoRespDelay_AFTx: %d - autoRespDelay_ReTx: %d\r\n", autoRespDelay_AFTx, autoRespDelay_ReTx);
409                break;
410               
411            case ASCII_r:
412                autoRespDelay_AFTx--;
413                autoRespDelay_ReTx--;
414                xil_printf("autoRespDelay_AFTx: %d - autoRespDelay_ReTx: %d\r\n", autoRespDelay_AFTx, autoRespDelay_ReTx);
415                break;
416           
417               
418            case ASCII_q:
419                ignoreSeqNums = (ignoreSeqNums ^ 1)%2;
420                xil_printf("Ignore seq nums: %d\r\n", ignoreSeqNums);
421                break;
422
423            case ASCII_N:
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);
428                break;
429               
430            case ASCII_n:
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);
435                break;
436
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;
450               
451            case ASCII_m:
452               
453                break;
454               
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){
473   
474        case BUZZER_TIMER:
475       
476            warp_userioboard_set_buzzer_en(0);
477        //  xil_printf("!\r\n");
478        break;
479        case TIMEOUT_TIMER:
480       
481            if(!relayMode)
482            {
483                //Source sent a DATA but never got ACK or NACK; time to re-transmit or give up
484               
485                //Check if this will be our last transmission attempt
486                if(txBuffer.remainingTx == 1)
487                {
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
492                    //Overwrite the relay address to our own, disabling cooperation from now on
493                    txBuffer.header.relAddr = NODEID_TO_ADDR(myID);
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
505               
506               
507               
508                autoResp_action_coopTx = 0;
509                mimo_ofdmTxRx_setAction4(autoResp_action_coopTx);
510               
511
512
513               
514               
515                //De-assert relay mode
516                relayMode = 0;
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
522                //warpmac_setDebugGPIO(0xF);
523                warpphy_AFrecordEnable(1);
524            }
525        break;//END TIMEOUT_TIMER
526
527        case BACKOFF_TIMER:
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            {
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               
543                //Re-transmit the packet
544                warpmac_startPhyXmit(pktBuf_tx_DATA);
545
546                //Wait for it to finish
547                warpmac_finishPhyXmit();
548                            warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA_SWAPPED);
549                //Start the timeout interval immediately after the Tx finishes
550                warpmac_setTimer(TIMEOUT_TIMER);
551
552                //Decrement the packet's remaining transmisisons
553                txBuffer.remainingTx = txBuffer.remainingTx - 1;
554               
555               
556            }
557        break;//END BACKOFF_TIMER
558    }
559}
560
561
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;
634    chan = controlStruct->channel;
635    warpphy_setChannel(GHZ_2, chan);
636   
637    xil_printf("Channel = %d\r\n",chan);
638    //xil_printf("LEN: %d, Period: %d\r\n",pktGen_length,pktGen_period);
639}
640
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
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
653void mgmtFromNetworkLayer_callback(Xuint32 length, char* payload){
654
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
779}
780
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
788void dataFromNetworkLayer_callback(Xuint32 length, char* payload){
789
790    unsigned char rxSeqNum;
791    unsigned char destNode;
792    unsigned char relayNode;
793   
794    warpnetRTObserve rtObserve;
795    warpnetControllerGroup controllerGroup;
796    XTime timeStamp;
797   
798    XTime_GetTime(&timeStamp);
799
800   
801
802//  xil_printf("data from network Layer\r\n");
803
804    //Disable any new packets until we're finished with this one
805    warpmac_disableDataFromNetwork();
806
807    warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA);
808   
809    //Reset the contention window to its smallest size for this exchange
810    warpmac_resetCurrentCW();
811
812    //Update the Tx pkt buffer index if we're cycling through them (for non-Ethernet traffic testing only)
813    if(randomData_Mode){
814        pktBuf_tx_DATA = (((pktBuf_tx_DATA+1)%25) + 4);
815        warpmac_setPHYTxBuffer(pktBuf_tx_DATA);
816    }
817
818
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);
822
823    //For now, assume our destination is our opposite ID (all traffic is 0 <-> 1)
824    // and the node 2 is always our relay
825    destNode = (myID+1)%2;
826   
827    if(alternating&&currentAlt){
828        relayNode = 2;
829    }
830    else{
831        relayNode = myID;
832    }
833
834//relayNode = 2;
835   
836//xil_printf("RELAY NODE%d\r\n",relayNode);
837
838    //Increment the sequence number for this destination
839    txSequences[destNode] = ( (txSequences[destNode]+1) & 0xFFFF);
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
853
854   
855    //Copy the header over to the DATA Tx packet buffer
856    warpmac_prepPhyForXmit(&txBuffer, pktBuf_tx_DATA);
857
858
859    if(enableStats) stats_numDataTx[destNode][myID][currentAlt]++;
860    currentAlt = (currentAlt+1)%2; 
861
862    //Packet is ready for transmission
863    if(warpmac_carrierSense()){
864        //Medium is idle; transmit right away
865        warpmac_startPhyXmit(pktBuf_tx_DATA);
866       
867        ////CRH
868        //              xil_printf("****TRANSMIT****\r\n");
869        //              unsigned int test = 64;
870        //              unsigned int testIndex;
871                       
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");
876    ////CRH
877
878        //Wait for it to finish and enable the receiver
879        warpmac_finishPhyXmit();
880        warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA_SWAPPED);
881
882        //Start a timeout timer
883        warpmac_setTimer(TIMEOUT_TIMER);
884
885        //Decrement the remaining resent counter
886        if(txBuffer.remainingTx > 0){
887            txBuffer.remainingTx = txBuffer.remainingTx - 1;
888        }
889    }
890   
891    else{
892        //Medium was busy in the last DIFS period; wait a random backoff before transmitting
893        warpmac_setTimer(BACKOFF_TIMER);
894    }
895   
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   
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() {
940
941   
942    userIOBoard_LEDs = userIOBoard_LEDs==0x80 ? 0x01 : (userIOBoard_LEDs << 1);
943
944    if(enableStats) stats_numBadHeaderRx++;
945
946   
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
956   
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
966int phyRx_goodHeader_callback(Macframe* packet){
967
968int manualClear = 0;
969
970
971
972warpmac_setDebugGPIO(0x1,0x1);
973        unsigned int currPhaseInc;
974    unsigned char state=PHYRXSTATUS_INCOMPLETE;
975    unsigned char srcNode,dstNode,relNode,relMode;
976    unsigned char shouldSend = 0;
977    warpnetRTObserve rtObserve;
978    warpnetControllerGroup controllerGroup;
979    XTime timeStamp;
980    int i;
981    shouldSend = 0;
982   
983    XTime_GetTime(&timeStamp);
984   
985    controllerGroup.controllerID = 0;
986    controllerGroup.controllerGrp = 0;
987    controllerGroup.access = 1;
988   
989    //Extract the source node ID from the packet's source address
990    srcNode = ADDR_TO_NODEID(packet->header.srcAddr);
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);
1006   
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                       
1014
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   
1028    //Debug-only: print AGC values for this packet
1029    if(agcPrintMode)
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   
1037    //Rotate the ring of LEDs clockwise
1038    userIOBoard_LEDs = userIOBoard_LEDs==0x1 ? 0x80 : (userIOBoard_LEDs >> 1);
1039   
1040    //Print the header (debug only- completely ruins actual performance)
1041#if 0
1042    xil_printf("Rx Header: ");
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
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);
1059                if(txBuffer.remainingTx > 0){
1060                    txBuffer.remainingTx = txBuffer.remainingTx - 1;                   
1061                }
1062            break;
1063
1064            default:
1065                //This should never, ever happen...
1066            break;
1067        }
1068
1069        //return;
1070    }
1071   
1072    //If the packet is addressed to this node
1073    if(packet->header.destAddr == ( NODEID_TO_ADDR(myID)) ) {
1074
1075        switch(packet->header.pktType){
1076            case DATAPACKET:
1077               
1078                if((packet->header.length)>1400){
1079                    updateLCD();
1080                }
1081
1082                state = warpmac_finishPhyRecv();
1083               
1084                if(state&PHYRXSTATUS_GOOD){
1085                    //Go, go autoResponder ACK!
1086                    warpmac_incrementLEDHigh();
1087                   
1088                   
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);
1093                        //CRH - NACK CHARACTERIZATION
1094                            if(enableStats) stats_numDataRx[packet->header.destAddr][packet->header.srcAddr][relMode]++;
1095                        //CHR
1096                        //shouldSend = 1;
1097                    }
1098                   
1099
1100                   
1101                    ////
1102                    //warp_userioboard_buzzer_set(PERHIGH, DUTYHIGH);
1103                    //warp_userioboard_set_buzzer_en(1&buzzerEnable);
1104                    //warpmac_setTimer(BUZZER_TIMER);
1105                    ////
1106                   
1107                    //Update the right-hex display with the current resend count for the received pkt
1108                    warpmac_leftHex(0xF & (packet->header.seqNum));
1109                   
1110                    //Starts the DMA transfer of the payload into the EMAC
1111                    if(shouldSend)
1112                    {
1113
1114                        warpmac_prepPktToNetwork((void *)warpphy_getBuffAddr(pktBuf_rx)+NUM_HEADER_BYTES, (packet->header.length));
1115                       
1116                       
1117                    //  xil_printf("****RECEIVE**\r\n");
1118                    //  unsigned int test = 64;
1119                    //  unsigned int testIndex;
1120                       
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");
1125                       
1126                        warpmac_finishPhyXmit();//? needed?
1127                        warpmac_startPktToNetwork(packet->header.length);
1128                       
1129
1130
1131                       
1132                    }
1133                   
1134                }
1135               
1136                if(state&PHYRXSTATUS_BAD){
1137                warpmac_incrementLEDLow();
1138                    //Go, go autoReponder NACK!
1139                    //CRH - NACK CHARACTERIZATION
1140                    if(enableStats) stats_numNACKTx[packet->header.srcAddr][myID][relMode]++;
1141                    //CHR
1142                   
1143                    ////
1144
1145                    //warp_userioboard_buzzer_set(PERLOW, DUTYLOW);
1146                    //warp_userioboard_set_buzzer_en(1&buzzerEnable);
1147                    //warpmac_setTimer(BUZZER_TIMER);
1148                    ////
1149
1150
1151                   
1152                   
1153                    //Rotate the ring of LEDs counter-clockwise
1154                    userIOBoard_LEDs = userIOBoard_LEDs==0x80 ? 0x01 : (userIOBoard_LEDs << 1);
1155                   
1156                }
1157           
1158            break;//END DATAPACKET
1159               
1160            case ACKPACKET:
1161                pktCount_good++;
1162
1163
1164                //Clear the timeout timer, set when we transmitted the data packet
1165                warpmac_clearTimer(TIMEOUT_TIMER);
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
1174                warpmac_setTimer(BACKOFF_TIMER);
1175
1176            break;//END ACKPACKET
1177               
1178            case NACKPACKET:
1179               
1180                if(warpmac_inTimeout())
1181                {
1182
1183                //CRH - NACK CHARACTERIZATION
1184                if(enableStats) stats_numNACKRx[packet->header.destAddr][packet->header.srcAddr][relMode]++;
1185                //CHR
1186               
1187                    //Go, go autoResponder DATA reTx (if it's still enabled)!
1188
1189
1190
1191                    //Clear the timeout timer, set when we transmitted the data packet
1192                    warpmac_clearTimer(TIMEOUT_TIMER);
1193
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);
1207
1208                        //Wait for the transmission to finish the autoRepsonse trigger re-trasnmit
1209                        warpmac_finishPhyXmit();
1210
1211                        //Start a timeout, waiting for a ACK/NACK
1212                        warpmac_setTimer(TIMEOUT_TIMER);
1213
1214                       
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
1227                       
1228                    }
1229                }
1230                else if(warpmac_inBackoff())
1231                {
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);
1240                }
1241                else
1242                {
1243                        //warp_userioboard_set_buzzer_en(1);
1244                }
1245            break;//END NACKPACKET
1246        }
1247
1248        //return;
1249    }//END dstAddr == self
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:
1257           
1258//              warpmac_setDebugGPIO(0xF);
1259
1260warpmac_setDebugGPIO(0x4,0x4);
1261
1262                state = warpmac_finishPhyRecv();
1263//                  warpmac_setDebugGPIO(0x0); 
1264   
1265                if((state&PHYRXSTATUS_GOOD)&&allowRelay){
1266warpmac_incrementLEDHigh();
1267           
1268//      if(enableStats) stats_numDataRx[myID][packet->header.srcAddr][relMode]++;
1269                    //We can cooperate on this packet
1270                    relayMode = 1;
1271                   
1272                    //Define and enable the cooperative autoResponse transmitter
1273                    //Flag A will already be set (that actor is always enabled)
1274                   
1275
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);
1279
1280
1281                   
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
1284       
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];
1290                   
1291                    //warpphy_setBuffs(pktBuf_tx_DATA, pktBuf_rx);
1292                    warpmac_setRxBuffers(&rxBuffer, pktBuf_rx);
1293                       
1294                   
1295                    warpphy_clearRxPktStatus();
1296                    manualClear = 1;
1297                   
1298                    relayDestID = ADDR_TO_NODEID(packet->header.destAddr);
1299                    relayLen = packet->header.length;
1300                    //Finally, start a timeout, waiting for a ACK/NACK
1301                    warpmac_clearTimer(TIMEOUT_TIMER);
1302                    warpmac_setTimer(TIMEOUT_TIMER);
1303                   
1304                    ////
1305                //warp_userioboard_buzzer_set(PERHIGH, DUTYHIGH);
1306                //warp_userioboard_set_buzzer_en(1&buzzerEnable);
1307                //warpmac_setTimer(BUZZER_TIMER);
1308                    ////
1309                   
1310                    return;
1311                    //DEBUG print
1312
1313                }
1314
1315                if(state&PHYRXSTATUS_BAD){
1316                warpmac_incrementLEDLow();
1317                                    ////
1318                //warp_userioboard_buzzer_set(PERLOW, DUTYLOW);
1319                //warp_userioboard_set_buzzer_en(1&buzzerEnable);
1320                //warpmac_setTimer(BUZZER_TIMER);
1321
1322                    ////
1323                    //Let the timeout handler reset things (like restarting AF capture, disabling coop autoResponse, etc.
1324                }
1325           
1326                   
1327            break;//END DATAPACKET
1328
1329            case NACKPACKET:
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);
1338
1339                    ////
1340                   
1341                if(relayMode) {
1342
1343
1344               
1345                    if(enableStats) if(enableStats) stats_numDataTx[packet->header.srcAddr][myID][relMode]++;
1346//CRH ADDME                 if(enableStats) stats_numDataTx[][]++;
1347                   
1348                   
1349
1350                    //Go, go autoRepsonder AF Tx!
1351
1352                   
1353                   
1354//                  warpmac_setDebugGPIO(0xF);
1355
1356                    //Clear the timeout (started when we recevied the DATA packet)
1357                    warpmac_clearTimer(TIMEOUT_TIMER);
1358                   
1359                    //Wait for the autoResponse transmission to finish
1360                    warpmac_finishPhyXmit();
1361
1362//                  warpmac_setDebugGPIO(0x0);
1363                    //Restart capturing the AF waveform, now that we've sent the good one we had
1364                    //warpmac_setDebugGPIO(0xF);
1365                    warpphy_AFrecordEnable(1);
1366
1367                    //Disable the cooperative autoResponse transmitter
1368                    autoResp_action_coopTx = 0;
1369                    mimo_ofdmTxRx_setAction4(autoResp_action_coopTx);
1370                   
1371       
1372
1373                   
1374                   
1375                    relayMode = 0;
1376                }
1377                else{
1378               
1379                }
1380            break;//END NACKPACKET
1381
1382            case ACKPACKET:
1383                //Clear the timeout (started when we recevied the DATA packet)
1384                warpmac_clearTimer(TIMEOUT_TIMER);
1385
1386                //Restart capturing the AF waveform, now that we've sent the good one we had
1387                //warpmac_setDebugGPIO(0xF);
1388                warpphy_AFrecordEnable(1);
1389               
1390                //Disable the cooperative autoResponse transmitter
1391                autoResp_action_coopTx = 0;
1392                mimo_ofdmTxRx_setAction4(autoResp_action_coopTx);
1393               
1394   
1395
1396       
1397               
1398               
1399                relayMode = 0;
1400            break;//END ACKPACKET
1401        }
1402    //  return;
1403    }
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);
1416
1417    }
1418   
1419    return manualClear;
1420
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
1429    cfoVar = 38;
1430    currentAnt = 0;
1431    chan = 4;
1432
1433    agcPrintMode = 0;
1434    randomData_Mode = 0;
1435   
1436    pktCount_good = 0;
1437    pktCount_bad = 0;
1438
1439    //Not a relay by default
1440    relayMode = 0;
1441
1442   
1443    debug_sisoMode = 0;
1444    ignoreSeqNums = 0;
1445   
1446       
1447    txPower = 0x3f;
1448   
1449    //Set the full-rate modulation to QPSK by default
1450//  pktFullRate = HDR_FULLRATE_QPSK;
1451    pktFullRate = HDR_FULLRATE_QAM_16;
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();
1459    max_numTransmissions = 2;
1460    warpmac_setMaxResend(max_numTransmissions);
1461    warpmac_setMaxCW(5);
1462
1463    //Select single-antenna Alamouti mode for both Tx and Rx
1464    if(debug_sisoMode)
1465    //  warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA);
1466    warpphy_setAntennaMode(TX_ANTMODE_ALAMOUTI_2ANT, RX_ANTMODE_ALAMOUTI_ANTA);
1467    else
1468        warpphy_setAntennaMode(TX_ANTMODE_ALAMOUTI_ANTA, RX_ANTMODE_ALAMOUTI_ANTA);
1469
1470    warpmac_setTimeout(140); //100
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
1475    myID = (unsigned short int)warpmac_getMyId();
1476    warpmac_leftHex(myID);
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];
1483    pktBuf_rx_emac = 3;
1484    pktBuf_tx_DATA = 4;
1485    pktBuf_tx_ACK = 29;
1486    pktBuf_tx_NACK = 30;
1487    pktBuf_tx_AF = 31;
1488
1489    cfoDly = 16;
1490    antB_preambleShift = 3;
1491
1492    autoRespDelay_NACKTx = 2; //100
1493    autoRespDelay_AFTx = 2;
1494    autoRespDelay_ReTx = 2;
1495    autoRespDelay_ACKTx = 0;
1496   
1497    rx_correThresh = 1400;
1498   
1499
1500   
1501    //Rx buffer is where the EMAC will DMA Wireless payloads from
1502    warpmac_setRxBuffers(&rxBuffer, pktBuf_rx);
1503    //Tx buffer is where the EMAC will DMA Ethernet payloads to
1504    warpmac_setPHYTxBuffer(pktBuf_tx_DATA);
1505    warpmac_setEMACRxBuffer(pktBuf_rx_emac);//VERY VERY IMPORTANT
1506   
1507    //Copy this node's MAC address into the Tx buffer's source address field
1508    txBuffer.header.srcAddr = (unsigned short int)( NODEID_TO_ADDR(myID) );
1509   
1510    //Register callbacks
1511
1512   
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   
1525    //Configure a buzzer tone, to be enabled on odd error conditions
1526//  warp_userioboard_buzzer_set(40000, 13107);
1527
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);
1535    warp_userio_lcd_printline("RefDesign v14", 16, 1, 1);
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
1546    warpmac_setCSMA(1);
1547
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
1559   
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
1625   
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));
1627    mimo_ofdmTxRx_setAction0(autoResp_action);
1628//  mimo_ofdmTxRx_setAction0(0); //Use this to disable ACKs
1629   
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
1632    mimo_ofdmTxRx_setAction1(autoResp_action);
1633   
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);
1636   
1637    autoResp_action = PHY_AUTORESPONSE_ACTION_SETFLAGA_CONFIG((REQ_RLY_ME | REQ_DATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
1638    mimo_ofdmTxRx_setAction3(autoResp_action);
1639   
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));
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);
1643   
1644/*****************************************/
1645/******** END autoResponse setup *******/
1646/*****************************************/
1647   
1648    //Enable local packet generation (ignoring Ethernet)
1649    warpmac_setDummyPacketMode(1);
1650   
1651    //Listen for new packets to send (either from Ethernet or local dummy packets)
1652    warpmac_enableDataFromNetwork();
1653   
1654    //Set the modulation scheme use for base rate (header) symbols
1655//  warpmac_setBaseRate(QPSK);
1656    warpmac_setBaseRate(BPSK);
1657   
1658    XTime rand_time;
1659    XTime_GetTime(&rand_time);
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   
1670    xil_printf("Reference Design v15.04 DOCMAC\r\n");
1671    xil_printf("Beginning main loop\r\n");
1672   
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
1678    //mimo_ofdmRx_setOptions(mimo_ofdmRx_getOptions() | BYPASS_CARR_REC, DEFAULT_STATUSBITS);
1679    //xil_printf("Carrier Rec Bypass\r\n");
1680
1681    //////
1682    int i,j;
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   
1692    //Hard-code which nodes send which Alamouti streams - relay always sense stream B
1693    if(myID == 0 || myID == 1)
1694        warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA);
1695    else if(myID == 2)
1696        warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA); //CRH
1697   
1698    //if(myID == 0)
1699    //{
1700    //Be the source
1701    //  warpmac_startPacketGeneration(1300, 1500); //900,1500
1702    //}
1703   
1704    respondToNacks = 1;
1705    buzzerEnable = 0;
1706   
1707    docPreambleScaling=2480;
1708    docPayloadScaling=9792;
1709    mimo_ofdmTx_setTxScaling(docPreambleScaling,docPayloadScaling);
1710    warpphy_setAntBPreambleShift(antB_preambleShift);
1711   
1712    warpphy_setTxPower(txPower);
1713   
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; 
1730
1731    sleep(8);
1732    unsigned char ethernetAddr[] = {0x00,0x50,0xC2,0x63,0x3F,0x80+myID};
1733    warpnet_setMacAddr((void*)&ethernetAddr);
1734    warpnet_sendGratuitousArp(myID);
1735
1736    ///////
1737   
1738    allowRelay = 0;
1739    alternating = 0;
1740//  if(myID==0) warpmac_startPacketGeneration(1300, 10000);
1741
1742warpphy_AFrecordEnable(0);
1743warpphy_AFrecordEnable(1);
1744   
1745    while(1){
1746        warpmac_pollPeripherals();     
1747    }
1748   
1749    return;
1750}
Note: See TracBrowser for help on using the repository browser.