source: ResearchApps/MAC/Debug_PseudoMACs/AFDF_CHAR/afdf_char.c

Last change on this file was 1618, checked in by murphpo, 13 years ago

Working towards refdes v16

File size: 52.5 KB
Line 
1/*! \file afdf_char.c
2 \brief Top-level "MAC" for characterizing AF and DF PHY performance
3 
4 @version 15.22
5 @author Patrick Murphy
6*/
7
8#include "xparameters.h"
9#include "warpnet.h"
10#include "warpmac.h"
11#include "warpphy.h"
12#include "afdf_char.h"
13#include "string.h"
14#include "stdlib.h"
15#include "stdio.h"
16#include "xtime_l.h"
17
18//Lower level includes, for debug/development
19#include "ofdm_txrx_mimo_regMacros.h"
20#include "ofdm_agc_mimo_regMacros.h"
21#include "warp_timer_regMacros.h"
22#include "radio_controller_basic.h"
23#include "radio_controller_ext.h"
24#include "radio_controller_adv.h"
25#include "radio_controller_5ghz.h"
26#include "ascii_characters.h"
27
28#define AF_ONLY 0
29#define DF_ONLY 0
30
31//Node IDs
32#define ID_SRC 0
33#define ID_DST 1
34#define ID_RLY 2
35
36//Packet types
37#define PKTTYPE_NCDATA 0x00
38#define PKTTYPE_DFDATA 0xEE
39#define PKTTYPE_AFDATA 0x55
40#define PKTTYPE_AFGHDATA 0xC3
41#define PKTTYPE_DFGHDATA 0x3C
42#define PKTTYPE_NCMHOPDATA 0xA2
43
44#define PKTTYPE_INVALID 0x88
45
46unsigned char pktTypesToTx[6];
47unsigned char numPktTypes;
48
49//Match unit assignments
50//#define REQ_DST_ME    PHY_AUTORESPONSE_REQ_MATCH0
51#define REQ_RLY_ME  PHY_AUTORESPONSE_REQ_MATCH0
52#define REQ_DFDATA  PHY_AUTORESPONSE_REQ_MATCH1
53#define REQ_AFDATA  PHY_AUTORESPONSE_REQ_MATCH2
54#define REQ_AFGHDATA    PHY_AUTORESPONSE_REQ_MATCH3
55#define REQ_DFGHDATA    PHY_AUTORESPONSE_REQ_MATCH4
56#define REQ_NCMHOPDATA  PHY_AUTORESPONSE_REQ_MATCH5
57
58int myID;
59unsigned char chan;
60unsigned int pktFullRate;
61unsigned int pktCodeRate;
62unsigned int pktGen_length, pktGen_period;
63
64unsigned char nonCoopTesting;
65unsigned char coopTesting;
66
67unsigned int autoResp_matchCond;
68unsigned int autoResp_action;
69unsigned int autoResp_action_relayTx;
70
71unsigned char pktBuf_rx;
72unsigned char pktBuf_tx_DATA;
73unsigned char pktBuf_emac_rx;
74unsigned char pktBuf_tx_AF;
75
76unsigned char autoRespDelay_SrcReTx;
77unsigned char autoRespDelay_RlyTx_DF;
78unsigned char autoRespDelay_RlyTx_AF;
79unsigned char pktDetBypass_txStartDly;
80
81unsigned char txPower;
82
83unsigned int preambleScaling;
84unsigned int payloadScaling;
85signed char agcTargetPwr;
86
87unsigned short pktDet_corrThresh;
88//unsigned char pktDet_corrWindowStart;
89//unsigned char pktDet_corrWindowEnd;
90//unsigned short longCorrCounterLoad;
91
92unsigned int afScaling;
93
94unsigned char reportCFOviaWarpnet;
95unsigned char reportBERviaWarpnet;
96unsigned char doRxPHYdump;
97
98unsigned char FFT_offset;
99unsigned int energyThresh;
100unsigned int agcThresholds;
101
102unsigned int agc_iirCoef_g, agc_iirCoef_fb;
103
104warpnetObservePER perStruct_NC;
105warpnetObservePER perStruct_DF;
106warpnetObservePER perStruct_AF;
107warpnetObservePER perStruct_AFGH;
108warpnetObservePER perStruct_DFGH;
109warpnetObservePER perStruct_NCMHOP;
110warpnetObservePER perStruct_Other;
111
112warpnetRxPHYdump rxPHYdumpStruct;
113
114warpnetControllerGroup groupStruct;
115
116Macframe rxFrame;
117Macframe txFrame;
118
119warpnetEthernetPktHeader txEthPktHeader;
120warpnetEthernetPktHeader coprocEthPktHeader;
121warpnetEthernetPktHeader coprocEthPktHeader;
122
123unsigned char curPktType;
124unsigned char curPktTypeInd;
125
126unsigned short int txSequences[3];
127
128void dataFromNetworkLayer_callback(Xuint32 length, char* payload)
129{
130    if(myID != ID_SRC)
131    {   
132        //Shouldn't happen; destination node won't start dummy pkt generation
133        warpmac_waitForDMA();
134        return;
135    }
136
137    void* txPktPtr;
138   
139    //Add to DF/AF cases to test coop-mhop
140    //mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & ~(TX_AUTO_TWOTX_EN));
141   
142    if(coopTesting) {
143        curPktTypeInd = (curPktTypeInd+1) % numPktTypes;
144        curPktType = pktTypesToTx[curPktTypeInd];
145       
146        if(curPktType == PKTTYPE_NCDATA) perStruct_NC.numPkts_tx++;
147        else if(curPktType == PKTTYPE_DFDATA) perStruct_DF.numPkts_tx++;
148        else if(curPktType == PKTTYPE_AFDATA) perStruct_AF.numPkts_tx++;
149        else if(curPktType == PKTTYPE_AFGHDATA) perStruct_AFGH.numPkts_tx++;
150        else if(curPktType == PKTTYPE_DFGHDATA) perStruct_DFGH.numPkts_tx++;
151        else if(curPktType == PKTTYPE_NCMHOPDATA) {
152            perStruct_NCMHOP.numPkts_tx++;
153            //Turn off two-Tx mode (gets re-enabled at end of this function)
154            mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & ~(TX_AUTO_TWOTX_EN));
155        }
156    } else {
157        curPktType = PKTTYPE_NCDATA;
158        perStruct_NC.numPkts_tx++;
159    }
160
161    //Increment the sequence number
162    //if(curPktType == PKTTYPE_NCDATA) {
163    if(curPktTypeInd == 0) {
164        //Only increment on the first packet of a cycle; this way NC/AF/DF all have same seq number, making log-file-parsing easier
165        txSequences[ID_DST] = ( (txSequences[ID_DST]+1) & 0xFFFF);
166    }
167
168    //Set the length field in the header
169    txFrame.header.length = length;
170
171    //Set the modulation scheme for the packet's full-rate symbols
172    txFrame.header.pktType = curPktType;
173    txFrame.header.srcAddr = (unsigned short int)(NODEID_TO_ADDR(ID_SRC));
174    txFrame.header.destAddr = (unsigned short int)(NODEID_TO_ADDR(ID_DST));
175    txFrame.header.relAddr = (unsigned short int)(NODEID_TO_ADDR(ID_RLY));
176    txFrame.header.fullRate = pktFullRate;
177    txFrame.header.codeRate = pktCodeRate;
178    txFrame.header.seqNum = txSequences[ID_DST];
179
180    //Copy the header over to Tx packet buffer
181    warpmac_prepPhyForXmit(&txFrame, pktBuf_tx_DATA);
182   
183    //Transmit the packet
184    if(coopTesting) {
185        //Configure the antenna mode (normal in slot1, swapped in slot2)
186        warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA);
187//      warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA_SWAPPED);
188
189        //Disable the TxStart output going to the destination
190        mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | (TX_START_D0_OUT_EN));
191        mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & ~(TX_START_D1_OUT_EN));
192
193        //Set the cyclic shift to 0
194        mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & ~(0x3F00000));
195
196        //Assert the dst node's pktDetReset for slot 1
197        warpmac_setDebugGPIO(0x4, 0xF);
198    }
199
200    warpmac_startPhyXmit(pktBuf_tx_DATA);
201
202    if(coopTesting) {
203        usleep(20);
204
205        mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & ~(TX_START_D0_OUT_EN));
206        mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | (TX_START_D1_OUT_EN));}
207
208    //Wait for it to finish
209    warpmac_finishPhyXmit();
210
211    if(coopTesting) {
212        usleep(8); //leave enough time for all the energy to get through the emulator, to avoid false pkt det at dest at end of slot 1
213        if(curPktType != PKTTYPE_NCDATA) {
214            warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA_SWAPPED);
215    //      warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA);
216        }
217
218        warpmac_setDebugGPIO(0x0, 0xF);
219
220        //Wait long enough for the relay to finish receiving slot1
221        usleep(autoRespDelay_SrcReTx/10);
222
223        //Assert the relay's pktDet reset for slot2; this needs to happen before the relay's long correlation asserts
224        warpmac_setDebugGPIO(0x2, 0xF);
225       
226        //PHY will start transmitting again automatically; wait for it to finish
227        usleep(4);
228        warpmac_finishPhyXmit();
229
230        //Keep relay pkt det reset long enough to avoid bogus detection at end of slot 2
231        usleep(10);
232        warpmac_setDebugGPIO(0x0, 0xF);
233
234        //Turn two-Tx mode back on (might have been disabled for NCMHOP)
235        mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | (TX_AUTO_TWOTX_EN));
236    }
237   
238   
239    if(reportBERviaWarpnet) {
240        //Send a copy of the just-transmitted packet to the BER calculating app
241        //BER packets are built from:
242        // Ethernet header [0:15]
243        // MAC/PHY header [0:23] generated above
244        // Actual transmitted payload (randomly generated and recorded in the PHY) [0:length-1]
245
246        coprocEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(phyHeader) + length;
247        coprocEthPktHeader.ethType = WARPNET_ETHTYPE_NODE2BER; 
248
249        txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2COPROC_PKTBUFFINDEX);
250        memcpy(txPktPtr, &(coprocEthPktHeader), sizeof(warpnetEthernetPktHeader));
251        txPktPtr += sizeof(warpnetEthernetPktHeader);
252        memcpy(txPktPtr, (void*)&(txFrame.header), sizeof(phyHeader));
253        txPktPtr += sizeof(phyHeader);
254       
255        memcpy(txPktPtr, (void *)(warpphy_getBuffAddr(pktBuf_tx_DATA)+sizeof(phyHeader)), length);
256
257        warpmac_prepPktToNetwork((void *)warpphy_getBuffAddr(WARPNET_NODE2COPROC_PKTBUFFINDEX), coprocEthPktHeader.pktLength);
258        warpmac_startPktToNetwork(coprocEthPktHeader.pktLength);
259    }
260    return;
261}
262
263///@brief Callback for the reception of bad wireless headers
264///
265///@param packet Pointer to received Macframe
266void phyRx_badHeader_callback() {
267    unsigned char tmp_pktType;
268
269    warpmac_incrementLEDLow();
270    tmp_pktType = * ( (unsigned char *)(warpphy_getBuffAddr(pktBuf_rx) + PKTHEADER_INDX_TYPE));
271   
272    //Trust the packet type field if it's one of the three valid values; otherwise set it to an invalid value before dumping
273    switch(tmp_pktType) {
274        case PKTTYPE_AFDATA:
275            perStruct_AF.numPkts_rx_badHdr++;
276            break;
277        case PKTTYPE_AFGHDATA:
278            perStruct_AFGH.numPkts_rx_badHdr++;
279            break;
280        case PKTTYPE_DFGHDATA:
281            perStruct_DFGH.numPkts_rx_badHdr++;
282            break;
283        case PKTTYPE_DFDATA:
284            perStruct_DF.numPkts_rx_badHdr++;
285            break;
286        case PKTTYPE_NCMHOPDATA:
287            perStruct_NCMHOP.numPkts_rx_badHdr++;
288            break;
289        case PKTTYPE_NCDATA:
290            perStruct_NC.numPkts_rx_badHdr++;
291            break;
292        default:
293            //Can't trust the type field; set the reported value to a known-invalid value
294            perStruct_Other.numPkts_rx_badHdr++;
295            tmp_pktType = PKTTYPE_INVALID;
296            break;
297    }
298           
299    if(doRxPHYdump) {
300        Send_RxPHYdump(1, 1, 1, 1, tmp_pktType, 0);
301    }
302
303    return;
304}
305
306
307///@brief Callback for the reception of good wireless headers
308///
309///This function then polls the PHY to determine if the entire packet passes checksum
310///thereby triggering the transmission of the received data over Ethernet.
311///@param packet Pointer to received Macframe
312int phyRx_goodHeader_callback(Macframe* packet)
313{
314    int i;
315    unsigned char state = PHYRXSTATUS_INCOMPLETE;
316   
317    void* txPktPtr;
318
319    unsigned char rxPktType;
320   
321    warpnetCFO cfoStruct;
322   
323    unsigned char* hdrPtr1;
324    unsigned char* hdrPtr2;
325   
326    hdrPtr1 = (unsigned char*)&(packet->header);
327    hdrPtr2 = (unsigned char*)(warpphy_getBuffAddr(pktBuf_rx));
328   
329    if( ((packet->header.srcAddr) != ID_SRC) | ((packet->header.destAddr) != ID_DST) | ((packet->header.relAddr) != ID_RLY)) {
330        //Fake good header event; call the bad header handler, then return
331        phyRx_badHeader_callback();
332        return 0; //let WARPMAC clear the PHY status bits once reception is done
333    }   
334   
335    rxPktType = (packet->header.pktType);
336
337    if(reportCFOviaWarpnet) {
338        cfoStruct.structID = STRUCTID_CFO;
339        cfoStruct.nodeID = myID;
340        cfoStruct.sequenceNumber = (packet->header.seqNum);
341
342        //Read the coarse CFO estimate (ready after the preamble)
343        cfoStruct.cfo_c = warpphy_getPreCFO_pkt_coarse();
344
345        //The dst doesn't actually use this CFO, but providing it here makes log parsing much easier
346        cfoStruct.txCFO = warpphy_getPreCFO_pktBuf(pktBuf_tx_DATA);
347    }
348
349    if(reportBERviaWarpnet) {
350        //Send a copy of the just-received packet to the BER calculating app
351        //BER packets are built from:
352        // Ethernet header [0:15]
353        // MAC/PHY header [0:23] generated above
354        // Actual transmitted payload (randomly generated and recorded in the PHY) [0:length-1]
355        coprocEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(phyHeader) + (packet->header.length);
356        coprocEthPktHeader.ethType = WARPNET_ETHTYPE_NODE2BER; 
357
358        txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2COPROC_PKTBUFFINDEX);
359        memcpy(txPktPtr, &(coprocEthPktHeader), sizeof(warpnetEthernetPktHeader));
360        txPktPtr += sizeof(warpnetEthernetPktHeader);
361        memcpy(txPktPtr, (void*)&(packet->header), sizeof(phyHeader));
362        txPktPtr += sizeof(phyHeader);
363    }
364
365    //Blocks until the PHY declares the payload good or bad
366    state = warpmac_finishPhyRecv();
367
368    if(state & PHYRXSTATUS_GOOD)
369    {
370        warpmac_incrementLEDHigh();
371        cfoStruct.pktStatus = (unsigned int)ofdm_txrx_mimo_ReadReg_Rx_packet_done();
372
373        if(coopTesting) {
374            if(rxPktType == PKTTYPE_AFDATA) {
375                if(myID == ID_RLY) {
376                    perStruct_AF.numPkts_tx++;
377                    warpphy_AFrecordEnable(0);
378                    usleep(autoRespDelay_RlyTx_AF/10);
379                    warpmac_finishPhyXmit();
380                    warpphy_AFrecordEnable(1);
381                }
382                perStruct_AF.numPkts_rx_good++;
383            }
384            else if(rxPktType == PKTTYPE_AFGHDATA) {
385                if(myID == ID_RLY) {
386                    perStruct_AFGH.numPkts_tx++;
387                    warpphy_AFrecordEnable(0);
388                    usleep(autoRespDelay_RlyTx_AF/10);
389                    warpmac_finishPhyXmit();
390                    warpphy_AFrecordEnable(1);
391                }
392                perStruct_AFGH.numPkts_rx_good++;
393            }
394            else if(rxPktType == PKTTYPE_DFDATA) {
395                if(myID == ID_RLY) perStruct_DF.numPkts_tx++;
396                perStruct_DF.numPkts_rx_good++;
397            }
398            else if(rxPktType == PKTTYPE_DFGHDATA) {
399                if(myID == ID_RLY) perStruct_DFGH.numPkts_tx++;
400                perStruct_DFGH.numPkts_rx_good++;
401            }
402            else if(rxPktType == PKTTYPE_NCMHOPDATA) {
403                if(myID == ID_RLY) perStruct_NCMHOP.numPkts_tx++;
404                perStruct_NCMHOP.numPkts_rx_good++;
405            }
406            else if(rxPktType == PKTTYPE_NCDATA) {
407                perStruct_NC.numPkts_rx_good++;
408            }
409        } else {
410            perStruct_NC.numPkts_rx_good++;
411        }
412
413    }
414    else if(state & PHYRXSTATUS_BAD)
415    {
416        warpmac_incrementLEDLow();
417        cfoStruct.pktStatus = (unsigned int)ofdm_txrx_mimo_ReadReg_Rx_packet_done();
418
419        if(coopTesting) {
420            if(rxPktType == PKTTYPE_AFDATA)
421                perStruct_AF.numPkts_rx_goodHdrBadPyld++;
422            else if(rxPktType == PKTTYPE_AFGHDATA) {
423                if(myID == ID_RLY) {
424                    perStruct_AFGH.numPkts_tx++;
425                    warpphy_AFrecordEnable(0);
426                    usleep(autoRespDelay_RlyTx_AF/10);
427                    warpmac_finishPhyXmit();
428                    warpphy_AFrecordEnable(1);
429                }
430                perStruct_AFGH.numPkts_rx_goodHdrBadPyld++;
431            }
432            else if(rxPktType == PKTTYPE_DFDATA)
433                perStruct_DF.numPkts_rx_goodHdrBadPyld++;
434            else if(rxPktType == PKTTYPE_DFGHDATA) {
435                if(myID == ID_RLY) perStruct_DFGH.numPkts_tx++;
436                perStruct_DFGH.numPkts_rx_goodHdrBadPyld++;
437            }
438            else if(rxPktType == PKTTYPE_NCMHOPDATA)
439                perStruct_NCMHOP.numPkts_rx_goodHdrBadPyld++;
440            else if(rxPktType == PKTTYPE_NCDATA)
441                perStruct_NC.numPkts_rx_goodHdrBadPyld++;
442        } else {
443            perStruct_NC.numPkts_rx_goodHdrBadPyld++;
444        }
445    }
446
447    if(reportCFOviaWarpnet) {
448        //Read the final CFO estimate (ready after the payload)
449        cfoStruct.cfo_p = warpphy_getPreCFO_pkt_pilots();
450        cfoStruct.cfo_b = warpphy_getPreCFO_pktBuf(pktBuf_rx);
451
452        //Construct the CFO struct and send it to the server
453        txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetControllerGroup) + sizeof(warpnetCFO);
454
455        txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
456        memcpy(txPktPtr, &(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
457        memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader), &(groupStruct), sizeof(warpnetControllerGroup));
458        memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader)+sizeof(warpnetControllerGroup), &(cfoStruct), sizeof(warpnetCFO));
459       
460        warpmac_prepPktToNetwork((void *)txPktPtr, txEthPktHeader.pktLength);
461        warpmac_startPktToNetwork(txEthPktHeader.pktLength);
462    }
463
464    if(reportBERviaWarpnet) {
465        memcpy(txPktPtr, (void *)(warpphy_getBuffAddr(pktBuf_rx)+sizeof(phyHeader)), packet->header.length);
466
467        warpmac_prepPktToNetwork((void *)warpphy_getBuffAddr(WARPNET_NODE2COPROC_PKTBUFFINDEX), coprocEthPktHeader.pktLength);
468        warpmac_startPktToNetwork(coprocEthPktHeader.pktLength);
469    }
470
471    //POM- only send PHYdump on GHBP or BH
472//  if(doRxPHYdump && (state & PHYRXSTATUS_BAD) ) {
473    if(doRxPHYdump) {
474        Send_RxPHYdump(1, 1, 1, 1, packet->header.pktType, packet->header.seqNum);
475    }
476   
477    //Return 1, indicating this function already waited for and cleared the PHY Rx status bits
478    warpphy_clearRxPktStatus();
479
480    return 1;
481}
482
483void uartRecv_callback(unsigned char uartByte)
484{
485    if(uartByte != 0x0)
486    {
487        xil_printf("(%c)\t", uartByte);
488       
489        switch(uartByte)
490        {
491            case ASCII_1:
492                pktFullRate = HDR_FULLRATE_BPSK;
493                xil_printf("Tx Full Rate = BPSK\r\n");
494                break;
495            case ASCII_2:
496                pktFullRate = HDR_FULLRATE_QPSK;
497                xil_printf("Tx Full Rate = QPSK\r\n");
498                break;
499            case ASCII_4:
500                pktFullRate = HDR_FULLRATE_QAM_16;
501                xil_printf("Tx Full Rate = 16-QAM\r\n");
502                break;
503            case ASCII_6:
504                pktFullRate = HDR_FULLRATE_QAM_64;
505                xil_printf("Tx Full Rate = 64-QAM\r\n");
506                break;
507            case ASCII_F:
508                if(chan<14) chan++;
509                warpphy_setChannel(GHZ_2, chan);
510                xil_printf("Current channel: %d\r\n",chan);
511                break;
512            case ASCII_f:
513                if(chan>1) chan--;
514                warpphy_setChannel(GHZ_2, chan);
515                xil_printf("Current channel: %d\r\n",chan);
516                break;
517            case ASCII_S:
518                warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTB, RX_ANTMODE_SISO_ANTB);
519                xil_printf("SISO Mode - Radio 3 Selected\r\n");
520                break;
521            case ASCII_s:
522                warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA);
523                xil_printf("SISO Mode - Radio 2 Selected\r\n");
524                break;
525            case ASCII_a:
526                afScaling -= 128;
527                mimo_ofdmRx_setAFTxScaling(afScaling);
528                xil_printf("AF Scaling: %d\r\n", afScaling);
529                break;
530            case ASCII_A:
531                afScaling += 128;
532                mimo_ofdmRx_setAFTxScaling(afScaling);
533                xil_printf("AF Scaling: %d\r\n", afScaling);
534                break;
535            case ASCII_G:
536                agcTargetPwr++;
537                ofdm_AGC_SetTarget(agcTargetPwr);
538                xil_printf("AGC target: %d\r\n", agcTargetPwr);
539                break;
540            case ASCII_g:
541                agcTargetPwr--;
542                ofdm_AGC_SetTarget(agcTargetPwr);
543                xil_printf("AGC target: %d\r\n", agcTargetPwr);
544                break;
545            case ASCII_X:
546                warpphy_incrementTxScaling(10, 0);
547                break;
548            case ASCII_x:
549                warpphy_incrementTxScaling(-10, 0);
550                break;
551            case ASCII_Y:
552                warpphy_incrementTxScaling(0, 10);
553                break;
554            case ASCII_y:
555                warpphy_incrementTxScaling(0, -10);
556                break;
557            case ASCII_W:
558                FFT_offset = FFT_offset + 1;
559                xil_printf("FFT_offset: %d\r\n", FFT_offset);
560                mimo_ofdmRx_setFFTWindowOffset(FFT_offset);
561                break;
562            case ASCII_w:
563                FFT_offset = (FFT_offset == 0) ? 0 : (FFT_offset - 1);
564                xil_printf("FFT_offset: %d\r\n", FFT_offset);
565                mimo_ofdmRx_setFFTWindowOffset(FFT_offset);
566                break;
567            case ASCII_D:
568                energyThresh += 100;
569                xil_printf("PktDet Thresh: %d\r\n", energyThresh);
570                ofdm_txrx_mimo_WriteReg_Rx_PktDet_setThresh(energyThresh);
571                break;
572               
573            case ASCII_d:
574                energyThresh -= 100;
575                xil_printf("PktDet Thresh: %d\r\n", energyThresh);
576                ofdm_txrx_mimo_WriteReg_Rx_PktDet_setThresh(energyThresh);
577                break;
578
579            case ASCII_C:
580                pktDet_corrThresh += 50;
581                xil_printf("LongCorr: %d\r\n", pktDet_corrThresh);
582                warpphy_setLongCorrThresh(pktDet_corrThresh);
583                break;
584            case ASCII_c:
585                pktDet_corrThresh -= 50;
586                xil_printf("LongCorr: %d\r\n", pktDet_corrThresh);
587                warpphy_setLongCorrThresh(pktDet_corrThresh);
588                break;
589               
590            case ASCII_T:
591                txPower++;
592                xil_printf("Tx Pwr: %d\r\n", txPower);
593                warpphy_setTxPower(txPower);
594                break;
595            case ASCII_t:
596                txPower--;
597                xil_printf("Tx Pwr: %d\r\n", txPower);
598                warpphy_setTxPower(txPower);
599                break;
600               
601            default:
602                xil_printf("Undefined command\r\n");
603                break;
604        }
605    }
606   
607    return;
608}
609
610void mgmtFromNetworkLayer_callback(Xuint32 length, char* payload) {
611   
612    void* rxPktPtr;
613    void* txPktPtr;
614   
615    int i, numRxStructs;
616    unsigned char rxSeqNum, theStructID;
617   
618    //Typed pointers for interpreting received structs
619    warpnetEthernetPktHeader* pktHeader;
620    warpnetControllerGroup* groupStructCopy;
621    warpnetCommand* commandStruct;
622    warpnetControl* controlStruct;
623    warpnetPHYctrl* phyCtrlStruct;
624    warpnetRequest* reqStruct;
625
626    warpnetObservePER* perStructPtr;
627    warpnetPERreq* perReqPtr;
628    unsigned char tmpReqType;
629   
630    //Local ACK struct, used to send responses to the server
631    warpnetAck ackStruct;
632
633    //Interpret the received bytes as an Ethernet packet
634    pktHeader = (warpnetEthernetPktHeader*)payload;
635   
636    if((pktHeader->ethType) != WARPNET_ETHTYPE_SVR2NODE) {
637        //Should never happen; all management packets are type WARPNET_ETHTYPE_SVR2NODE
638        return;
639    }
640   
641    numRxStructs = pktHeader->numStructs;
642    rxSeqNum = pktHeader->seqNum;
643
644    //Initialize the rx pointer to the first byte past the Ethernet header
645    rxPktPtr = (void*)(payload + sizeof(warpnetEthernetPktHeader));
646
647    //Iterate over each pair of warpnetControllerGroup / otherStruct in the server message
648    for(i=0; i<numRxStructs; i++) {
649
650        if( ( ((int)rxPktPtr) - ((int)payload) ) >= length) {
651            xil_printf("Error! Mgmt pktLength too short for numStructs\r\n");
652            return;
653        }
654       
655        //Alternate structs (starting with the first) are always warpnetControllerGroup
656        groupStructCopy = (warpnetControllerGroup*)rxPktPtr;
657        rxPktPtr += sizeof(warpnetControllerGroup);
658   
659        //Extract the first byte of the actual struct and interpret as the structID
660        theStructID = *( (unsigned char *)rxPktPtr );
661        //xil_printf("Mgmt Pkt: StructID=0x%x\r\n", theStructID);
662       
663        switch(theStructID)
664        {
665            case STRUCTID_COMMAND:
666                commandStruct = (warpnetCommand*)rxPktPtr;
667                rxPktPtr += sizeof(warpnetCommand);
668
669                if((commandStruct->nodeID) == myID) {
670
671                    //Send an ACK struct back to the server
672                    ackStruct.structID = STRUCTID_COMMAND_ACK;
673                    ackStruct.nodeID = myID;
674                    ackStruct.cmdID = commandStruct->cmdID;
675                   
676                    txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetControllerGroup) + sizeof(warpnetAck);
677                    txEthPktHeader.numStructs = 1;
678                   
679                    txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
680                    memcpy(txPktPtr, (void *)&(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
681                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader), (void *)groupStructCopy, sizeof(warpnetControllerGroup));
682                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader)+sizeof(warpnetControllerGroup), (void *)&(ackStruct), sizeof(warpnetAck));
683
684                    warpmac_prepPktToNetwork(txPktPtr, txEthPktHeader.pktLength);
685                    warpmac_startPktToNetwork(txEthPktHeader.pktLength);
686
687                    //Process the received struct
688                    processCommand(commandStruct);
689                }
690                break;
691               
692            case STRUCTID_CONTROL:
693                controlStruct = (warpnetControl*)rxPktPtr;
694                rxPktPtr += sizeof(warpnetControl);
695
696                if((controlStruct->nodeID) == myID) {
697                   
698                    //Send an ACK struct back to the server
699                    ackStruct.structID = STRUCTID_CONTROL_ACK;
700                    ackStruct.nodeID = myID;
701                   
702                    txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetControllerGroup) + sizeof(warpnetAck);
703                    txEthPktHeader.numStructs = 1;
704                   
705                    txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
706                    memcpy(txPktPtr, (void *)&(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
707                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader), (void *)groupStructCopy, sizeof(warpnetControllerGroup));
708                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader)+sizeof(warpnetControllerGroup), (void *)&(ackStruct), sizeof(warpnetAck));
709                   
710                    warpmac_prepPktToNetwork(txPktPtr, txEthPktHeader.pktLength);
711                    warpmac_startPktToNetwork(txEthPktHeader.pktLength);
712                   
713                    //Process the received struct
714                    processControl(controlStruct);
715                }
716                break;
717            case STRUCTID_PHYCTRL:
718                phyCtrlStruct = (warpnetPHYctrl*)rxPktPtr;
719                rxPktPtr += sizeof(warpnetPHYctrl);
720               
721                if((phyCtrlStruct->nodeID) == myID) {
722                    //Send an ACK struct back to the server
723                    ackStruct.structID = STRUCTID_PHYCTRL_ACK;
724                    ackStruct.nodeID = myID;
725                   
726                    txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetControllerGroup) + sizeof(warpnetAck);
727                    txEthPktHeader.numStructs = 1;
728                   
729                    txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
730                    memcpy(txPktPtr, (void *)&(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
731                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader), (void *)groupStructCopy, sizeof(warpnetControllerGroup));
732                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader)+sizeof(warpnetControllerGroup), (void *)&(ackStruct), sizeof(warpnetAck));
733                   
734                    warpmac_prepPktToNetwork(txPktPtr, txEthPktHeader.pktLength);
735                    warpmac_startPktToNetwork(txEthPktHeader.pktLength);
736                   
737                    //Process the received struct
738                    processPHYControl(phyCtrlStruct);
739                }
740                break;
741            case STRUCTID_OBSERVE_PER_REQ:
742                perReqPtr = (warpnetPERreq*)rxPktPtr;
743                rxPktPtr += sizeof(warpnetPERreq);
744
745                if((perReqPtr->nodeID) == myID) {
746                   
747                    if(coopTesting) {
748                        tmpReqType = (unsigned char)perReqPtr->reqType;
749
750                        if(tmpReqType == PKTTYPE_DFDATA)
751                            perStructPtr = &perStruct_DF;
752                        else if(tmpReqType == PKTTYPE_AFDATA)
753                            perStructPtr = &perStruct_AF;
754                        else if(tmpReqType == PKTTYPE_AFGHDATA)
755                            perStructPtr = &perStruct_AFGH;
756                        else if(tmpReqType == PKTTYPE_DFGHDATA)
757                            perStructPtr = &perStruct_DFGH;
758                        else if(tmpReqType == PKTTYPE_NCMHOPDATA)
759                            perStructPtr = &perStruct_NCMHOP;
760                        else if(tmpReqType == PKTTYPE_INVALID)
761                            perStructPtr = &perStruct_Other;
762                        else //if(tmpReqType == PKTTYPE_NCDATA)
763                            perStructPtr = &perStruct_NC;
764
765                        perStructPtr->reqType = tmpReqType;
766                    } else {
767                        perStructPtr = &perStruct_NC;
768                    }
769
770                    perStructPtr->reqNum = (unsigned char)perReqPtr->reqNum;
771
772                    txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetControllerGroup) + sizeof(warpnetObservePER);
773                    txEthPktHeader.numStructs = 1;
774                   
775                    txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
776                    memcpy(txPktPtr, (void *)&(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
777                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader), (void *)groupStructCopy, sizeof(warpnetControllerGroup));
778                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader)+sizeof(warpnetControllerGroup), (void *)perStructPtr, sizeof(warpnetObservePER));
779                   
780                    warpmac_prepPktToNetwork(txPktPtr, txEthPktHeader.pktLength);
781                    warpmac_startPktToNetwork(txEthPktHeader.pktLength);
782                }
783                break;
784               
785            default:
786                //Unrecognized structID; do nothing
787                //xil_printf("Unknown structID: 0x%x\r\n", theStructID);
788                break;
789        }//END switch(theStructID)
790               
791               
792    }//END for(0...numStructs-1)
793       
794    return;
795}
796
797void processPHYControl(warpnetPHYctrl* phyCtrlStruct) {
798    //Interpret the PHY control parameters
799    //PHYCtrol params:
800    //param0: txStartOut delay
801    //param1: artificial txCFO
802    //param2: minPilotChanMag
803    //param3:
804    // [0-0x01]: PHYCTRL_BER_EN: enable BER reporting
805    // [1-0x02]: PHYCTRL_CFO_EN: enable CFO reporting
806    // [2-0x04]: PHYCTRL_PHYDUMP_EN: enable Rx PHY dumping
807    // [3-0x08]: PHYTRCL_EXTPKTDET_EN: use only ext pkt det
808    // [4-0x10]: PHYCTRL_COOP_EN: 0=nonCoop, 1=coopMode
809    // [5-0x20]: PHYCTRL_CFO_CORR_EN: 0=bypass CFO correction, 1=enable CFO correction
810    // [6-0x40]: PHYCTRL_SWAP_ANT: 0=AntA, 1=AntA_Swapped
811    //param4:
812    // [ 7:0]: src re-Tx delay
813    // [ 7:0]: relay AF Tx delay (only used when in COOP_TESTING)
814    // [15:8]: relay DF Tx delay (only used when in COOP_TESTING)
815    //param5:
816    // [17: 0]: AGC IIR coef FB
817    //param6: (0 ignores)
818    // [31:16]: H_BA minEstMag (UFix16_15)
819    // [15: 0]: H_AA minEstMag (UFix16_15)
820    //param7: (0 ignores)
821    // [27:16]: AF blank stop
822    // [11: 0]: AF blank start
823    //param8:
824    // [17: 0]: AGC IIR coef g
825    //param9: (Tx pkt types)
826    // [31: 0]: OR'd combination of PHYCTRL_TX_*
827   
828    int i;
829    unsigned int txCFO;
830    unsigned int minChanMag;
831    unsigned int configBits;
832   
833//param0
834    pktDetBypass_txStartDly = (phyCtrlStruct->param0) & 0xFF;
835    mimo_ofdmTx_setDelays(autoRespDelay_SrcReTx, 0, pktDetBypass_txStartDly);
836   
837//param1
838    txCFO = phyCtrlStruct->param1;
839    if(txCFO != 0) {
840        warpphy_setPreCFO_pktBuf(pktBuf_tx_DATA, txCFO);
841        mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | (TX_ALWAYS_USE_PRECFO));
842    } else {
843        warpphy_setPreCFO_pktBuf(pktBuf_tx_DATA, 0);
844        mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & (~TX_ALWAYS_USE_PRECFO));
845    }
846       
847//param2
848    minChanMag = (phyCtrlStruct->param2) & 0xFFF;
849    mimo_ofdmRx_setPilotCalcParams(minChanMag);
850
851//param3
852    configBits = (phyCtrlStruct->param3) & 0xFFFF;
853
854    reportCFOviaWarpnet = 0;
855    reportBERviaWarpnet = 0;
856    doRxPHYdump = 0;
857    coopTesting = 0;
858    nonCoopTesting = 0;
859   
860    if( configBits & 0x1 ) {
861        reportBERviaWarpnet = 1;
862    } else {
863        reportBERviaWarpnet = 0;
864    }
865
866    if( configBits & 0x2 ) {
867        reportCFOviaWarpnet = 1;
868    } else {
869        reportCFOviaWarpnet = 0;
870    }
871
872    if( configBits & 0x4 ) {
873        doRxPHYdump = 1;
874    } else {
875        doRxPHYdump = 0;
876    }
877
878    if( configBits & 0x8 ) {
879        //Bypass long correlation checking
880        ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) & ~(REQ_LONG_CORR));
881
882        //Set the correlation and energy thresholds to max values (effectively disabling them)
883        warpphy_setLongCorrThresh(0xFFFF);
884        ofdm_txrx_mimo_WriteReg_Rx_PktDet_setThresh(0xFFFF);
885       
886        //Enable external pktDet input and bypass coarse CFO (it uses the long correlator too)
887        ofdm_txrx_mimo_WriteReg_Rx_PktDet_extDetEn(1);
888        ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) | (BYPASS_CARR_REC));
889        warpphy_setPreCFOoptions( (PRECFO_USEPILOTS) );
890       
891        //Set the pktDet->payload delay
892        mimo_ofdmRx_setPktDetDly(48); //works together with phyCtrl0.param0 = 51 to line up coop tx/rx with fake pkt det
893    } else {
894        //Reset the various pktDetection-dependent parameters to their defaults
895        ofdm_txrx_mimo_WriteReg_Rx_PktDet_extDetEn(0);
896        ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) | (REQ_LONG_CORR));
897        ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) & ~(BYPASS_CARR_REC));
898        warpphy_setPreCFOoptions( (PRECFO_USECOARSE | PRECFO_USEPILOTS) );
899        warpphy_setLongCorrThresh(pktDet_corrThresh);
900        ofdm_txrx_mimo_WriteReg_Rx_PktDet_setThresh(energyThresh);
901        mimo_ofdmRx_setPktDetDly(124);
902    }       
903
904    if( configBits & 0x10 ) {
905        //Enable cooperative testing
906        coopTesting = 1;
907        nonCoopTesting = 0;
908        warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA);
909        ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) | (EXT_PKTDETRESET_EN));
910    } else {
911        //Disable cooperative testing
912        coopTesting = 0;
913        nonCoopTesting = 1;
914        warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA);
915        ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) & ~(EXT_PKTDETRESET_EN));
916    }
917   
918    if( configBits & 0x20 ) {
919        ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) & ~(BYPASS_CARR_REC));
920        warpphy_setPreCFOoptions( (PRECFO_USECOARSE | PRECFO_USEPILOTS) );
921//      warpphy_setPreCFOoptions( (PRECFO_USECOARSE) ); //POM- disabling pilot estimator for now!
922    } else {
923        ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) | BYPASS_CARR_REC);
924        warpphy_setPreCFOoptions( (PRECFO_USEPILOTS) );
925    }
926
927    if( configBits & 0x40 ) {
928        warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA_SWAPPED);
929    } else {
930        warpphy_setTxAntennaSwap(TX_ANTMODE_ALAMOUTI_ANTA);
931    }
932
933//param4
934    //Update role-specific parameters
935    if(myID == ID_SRC) {
936        autoRespDelay_SrcReTx = (phyCtrlStruct->param4) & 0xFF;
937        mimo_ofdmTx_setDelays(autoRespDelay_SrcReTx, 0, pktDetBypass_txStartDly);
938    }
939    else if(myID == ID_RLY) {
940        autoRespDelay_RlyTx_AF = ((phyCtrlStruct->param4) & 0xFF);
941        autoRespDelay_RlyTx_DF = (((phyCtrlStruct->param4) & 0xFF00)>>8);
942    }
943
944//param5: IIR coef FB //Fix18_17
945    if((phyCtrlStruct->param5) > 0) {
946        agc_iirCoef_fb = ((phyCtrlStruct->param5) & 0x3FFFF);
947        XIo_Out32(XPAR_OFDM_AGC_MIMO_PLBW_0_MEMMAP_DCO_IIR_COEF_FB, agc_iirCoef_fb);
948    }
949
950//param6: chan est mag masking
951    if((phyCtrlStruct->param6) > 0) {
952        ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) | CHANMAG_MASKING_EN);
953        warpphy_setChanEstMinMags( (phyCtrlStruct->param6) );//((phyCtrlStruct->param6) & 0xFFFF), ( ((phyCtrlStruct->param6) & 0xFFFF0000)>>16) );
954    } else {
955        ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) & ~(CHANMAG_MASKING_EN));
956        warpphy_setChanEstMinMags(0);//, 0);
957    }
958   
959//param7: AF interval masking
960    if((phyCtrlStruct->param7) > 0) {
961        //Set AF blanking interval (set to zeros to disable)
962        warpphy_setAFblanking((phyCtrlStruct->param7) & 0x0FFF, ( ((phyCtrlStruct->param7) & 0x0FFF0000)>>16));
963    } else {
964        //Set AF blanking interval (set to zeros to disable)
965        warpphy_setAFblanking(0, 0);
966    }
967   
968//param8: IIR coef G //UFix18_17
969    if((phyCtrlStruct->param8) > 0) {
970        agc_iirCoef_g = ((phyCtrlStruct->param8) & 0x3FFFF);
971        XIo_Out32(XPAR_OFDM_AGC_MIMO_PLBW_0_MEMMAP_DCO_IIR_COEF_GAIN, agc_iirCoef_g);
972    }
973   
974//param9: Scheme en/disable
975    if((phyCtrlStruct->param9) > 0x0) {
976        numPktTypes = 0;
977
978        if((phyCtrlStruct->param9) & 0x01) {pktTypesToTx[numPktTypes] = PKTTYPE_NCDATA; numPktTypes++;}
979        if((phyCtrlStruct->param9) & 0x02) {pktTypesToTx[numPktTypes] = PKTTYPE_DFDATA; numPktTypes++;}
980        if((phyCtrlStruct->param9) & 0x04) {pktTypesToTx[numPktTypes] = PKTTYPE_AFDATA; numPktTypes++;}
981        if((phyCtrlStruct->param9) & 0x08) {pktTypesToTx[numPktTypes] = PKTTYPE_AFGHDATA; numPktTypes++;}
982        if((phyCtrlStruct->param9) & 0x10) {pktTypesToTx[numPktTypes] = PKTTYPE_DFGHDATA; numPktTypes++;}
983        if((phyCtrlStruct->param9) & 0x20) {pktTypesToTx[numPktTypes] = PKTTYPE_NCMHOPDATA; numPktTypes++;}
984       
985        //Safety check- if no type was enabled, revert to NC only
986        if(numPktTypes == 0) {pktTypesToTx[numPktTypes] = PKTTYPE_NCDATA; numPktTypes = 1;}
987    }
988
989    setupNodeBehaviors();
990    return;
991}
992
993void processControl(warpnetControl* controlStruct) {
994    unsigned char newMod, newCode;
995   
996    pktGen_length = controlStruct->pktGen_length;
997    pktGen_period = controlStruct->pktGen_period;
998
999    txPower = ((controlStruct->txPower) & 0x3F);
1000    warpphy_setTxPower(txPower);
1001
1002    newMod = ((controlStruct->modOrderPayload) & 0xF);
1003    newCode = (((controlStruct->modOrderPayload) & 0xF0)>>4);
1004   
1005    switch(newMod) {
1006        case 1:
1007            pktFullRate = HDR_FULLRATE_BPSK;
1008            break;
1009        case 2:
1010            pktFullRate = HDR_FULLRATE_QPSK;
1011            break;
1012        case 4:
1013            pktFullRate = HDR_FULLRATE_QAM_16;
1014            break;
1015        case 6:
1016            pktFullRate = HDR_FULLRATE_QAM_64;
1017            break;
1018        default:
1019            pktFullRate = HDR_FULLRATE_QPSK;
1020            break;
1021    }
1022
1023    switch(newCode) {
1024        case HDR_CODE_RATE_12:
1025            pktCodeRate = HDR_CODE_RATE_12;
1026            break;
1027        case HDR_CODE_RATE_23:
1028            pktCodeRate = HDR_CODE_RATE_23;
1029            break;
1030        case HDR_CODE_RATE_34:
1031            pktCodeRate = HDR_CODE_RATE_34;
1032            break;
1033        case HDR_CODE_RATE_NONE:
1034            pktCodeRate = HDR_CODE_RATE_NONE;
1035            break;
1036        default:
1037            pktCodeRate = HDR_CODE_RATE_NONE;
1038            break;
1039    }
1040   
1041    switch(controlStruct->modOrderHeader) {
1042        case 1:
1043            warpmac_setBaseRate(BPSK);
1044            break;
1045        case 2:
1046            warpmac_setBaseRate(QPSK);
1047            break;
1048        default:
1049            warpmac_setBaseRate(QPSK);
1050            break;
1051    }
1052   
1053    chan = controlStruct->channel;
1054    warpphy_setChannel(GHZ_2, chan);
1055}
1056
1057void processCommand(warpnetCommand* commandStruct) {
1058    switch(commandStruct->cmdID){
1059        case COMMANDID_STARTTRIAL:
1060            warpmac_startPacketGeneration(pktGen_length, pktGen_period);
1061            break;
1062        case COMMANDID_STOPTRIAL:
1063            warpmac_stopPacketGeneration();
1064            break;
1065        case COMMANDID_RESET_PER:
1066            curPktType = PKTTYPE_NCDATA;
1067
1068            perStruct_NC.numPkts_tx = 0;
1069            perStruct_NC.numPkts_rx_good = 0;
1070            perStruct_NC.numPkts_rx_goodHdrBadPyld = 0;
1071            perStruct_NC.numPkts_rx_badHdr = 0;
1072
1073            if(coopTesting) {
1074                perStruct_DF.numPkts_tx = 0;
1075                perStruct_DF.numPkts_rx_good = 0;
1076                perStruct_DF.numPkts_rx_goodHdrBadPyld = 0;
1077                perStruct_DF.numPkts_rx_badHdr = 0;
1078               
1079                perStruct_AF.numPkts_tx = 0;
1080                perStruct_AF.numPkts_rx_good = 0;
1081                perStruct_AF.numPkts_rx_goodHdrBadPyld = 0;
1082                perStruct_AF.numPkts_rx_badHdr = 0;
1083               
1084                perStruct_AFGH.numPkts_tx = 0;
1085                perStruct_AFGH.numPkts_rx_good = 0;
1086                perStruct_AFGH.numPkts_rx_goodHdrBadPyld = 0;
1087                perStruct_AFGH.numPkts_rx_badHdr = 0;
1088               
1089                perStruct_DFGH.numPkts_tx = 0;
1090                perStruct_DFGH.numPkts_rx_good = 0;
1091                perStruct_DFGH.numPkts_rx_goodHdrBadPyld = 0;
1092                perStruct_DFGH.numPkts_rx_badHdr = 0;
1093               
1094                perStruct_NCMHOP.numPkts_tx = 0;
1095                perStruct_NCMHOP.numPkts_rx_good = 0;
1096                perStruct_NCMHOP.numPkts_rx_goodHdrBadPyld = 0;
1097                perStruct_NCMHOP.numPkts_rx_badHdr = 0;
1098               
1099                perStruct_Other.numPkts_tx = 0;
1100                perStruct_Other.numPkts_rx_good = 0;
1101                perStruct_Other.numPkts_rx_goodHdrBadPyld = 0;
1102                perStruct_Other.numPkts_rx_badHdr = 0;
1103            }
1104            break;
1105        default:
1106            //Unknown command; do nothing
1107            xil_printf("processCommand: unknown command: 0x%x\r\n", commandStruct->cmdID);
1108            break;
1109    }
1110
1111    return;
1112}
1113
1114//This function should only be called after the packet payload status is known!
1115void Send_RxPHYdump(int sendEVMperSC, int sendEVMperSym, int sendChanEstAA, int sendChanEstBA, unsigned char pktType, unsigned short seqNum) {
1116    void* txPktPtr;
1117    void* txPktPtr_d;
1118    int i;
1119   
1120    txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2COPROC_PKTBUFFINDEX);
1121   
1122    coprocEthPktHeader.ethType = WARPNET_ETHTYPE_NODE2COPROC;
1123    coprocEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetRxPHYdump);
1124    rxPHYdumpStruct.includedData = 0;
1125    rxPHYdumpStruct.rxStatus = mimo_ofdmRx_getPktStatus();
1126    rxPHYdumpStruct.rssi = (ofdm_txrx_mimo_ReadReg_Rx_PktDet_midPktRSSI_antA());
1127    rxPHYdumpStruct.rxGains = (ofdm_txrx_mimo_ReadReg_Rx_Gains(0));
1128    rxPHYdumpStruct.pktType = pktType;
1129    rxPHYdumpStruct.seqNum = seqNum;
1130    rxPHYdumpStruct.cfoEst_coarse = warpphy_getPreCFO_pkt_coarse();
1131    rxPHYdumpStruct.cfoEst_pilots = warpphy_getPreCFO_pkt_pilots();
1132   
1133    memcpy(txPktPtr, &(coprocEthPktHeader), sizeof(warpnetEthernetPktHeader));
1134    txPktPtr_d = txPktPtr + sizeof(warpnetEthernetPktHeader);
1135    txPktPtr += sizeof(warpnetEthernetPktHeader) + sizeof(warpnetRxPHYdump);
1136   
1137    if(sendEVMperSC) {
1138        coprocEthPktHeader.pktLength += RXPHYDUMP_SIZE_EVMPERSC;
1139        rxPHYdumpStruct.includedData |= RXPHYDUMP_INCLUDE_EVMPERSC;
1140
1141        memcpy(txPktPtr, (void *)XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_EVM_PERSC, RXPHYDUMP_SIZE_EVMPERSC);
1142        txPktPtr += RXPHYDUMP_SIZE_EVMPERSC;
1143    }
1144    if(sendEVMperSym) {
1145        coprocEthPktHeader.pktLength += RXPHYDUMP_SIZE_EVMPERSYM;
1146        rxPHYdumpStruct.includedData |= RXPHYDUMP_INCLUDE_EVMPERSYM;
1147
1148        memcpy(txPktPtr, (void *)XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_EVM_PERSYM, RXPHYDUMP_SIZE_EVMPERSYM);
1149        txPktPtr += RXPHYDUMP_SIZE_EVMPERSYM;
1150    }
1151    if(sendChanEstAA) {
1152        coprocEthPktHeader.pktLength += RXPHYDUMP_SIZE_CHANEST;
1153        rxPHYdumpStruct.includedData |= RXPHYDUMP_INCLUDE_CHANESTAA;
1154       
1155        //A-A estimates are the first set in the buffer
1156        memcpy(txPktPtr, (void *)XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_CHANNELESTIMATES, RXPHYDUMP_SIZE_CHANEST);
1157        txPktPtr += RXPHYDUMP_SIZE_CHANEST;
1158    }
1159    if(sendChanEstBA) {
1160        coprocEthPktHeader.pktLength += RXPHYDUMP_SIZE_CHANEST;
1161        rxPHYdumpStruct.includedData |= RXPHYDUMP_INCLUDE_CHANESTBA;
1162
1163        //B-A estimates are the third set in the buffer (after AA and AB)
1164        memcpy(txPktPtr, (void *)(XPAR_OFDM_TXRX_MIMO_PLBW_0_MEMMAP_CHANNELESTIMATES+2*RXPHYDUMP_SIZE_CHANEST), RXPHYDUMP_SIZE_CHANEST);
1165        txPktPtr += RXPHYDUMP_SIZE_CHANEST;
1166    }
1167   
1168    memcpy(txPktPtr_d, &(rxPHYdumpStruct), sizeof(warpnetRxPHYdump));
1169
1170    warpmac_prepPktToNetwork((void *)warpphy_getBuffAddr(WARPNET_NODE2COPROC_PKTBUFFINDEX), coprocEthPktHeader.pktLength);
1171    warpmac_startPktToNetwork(coprocEthPktHeader.pktLength);
1172}
1173
1174///@brief Main function
1175///
1176///This function configures MAC parameters, enables the underlying frameworks, and then loops forever.
1177int main(){     
1178    xil_printf("AFDF_CHAR v15.22\r\n");
1179   
1180    int i;
1181   
1182    curPktType = PKTTYPE_NCDATA;
1183   
1184    chan = 9;
1185
1186    pktBuf_rx = 1;
1187    pktBuf_tx_DATA = 0;
1188    pktBuf_emac_rx = 3;
1189    pktBuf_tx_AF = 31;
1190   
1191    txSequences[ID_SRC] = 0;
1192    txSequences[ID_DST] = 0;
1193    txSequences[ID_RLY] = 0;
1194   
1195    reportCFOviaWarpnet = 0;
1196    reportBERviaWarpnet = 0;
1197    doRxPHYdump = 0;
1198    nonCoopTesting = 1;
1199    coopTesting = 0;
1200   
1201    pktGen_length = 1412;
1202    pktGen_period = 10000;
1203
1204//Over the air delays (S->R delay = 0):
1205    autoRespDelay_SrcReTx = 251;
1206    autoRespDelay_RlyTx_DF = 104; //was 52 - doubled precision in v15.14
1207    autoRespDelay_RlyTx_AF = 104; //was 52 - doubled precision in v15.14
1208
1209//Emulator delays (S->R delay = 1µs)
1210    autoRespDelay_SrcReTx = 251;
1211    autoRespDelay_RlyTx_DF = 94;//was 47 - doubled precision in v15.14
1212    autoRespDelay_RlyTx_AF = 94;//was 47 - doubled precision in v15.14
1213    pktDetBypass_txStartDly = 80;
1214   
1215    //Set the full-rate modulation to QPSK by default
1216    pktFullRate = HDR_FULLRATE_QPSK;
1217    pktCodeRate = CODE_RATE_12;
1218   
1219    txPower = 0x3f;
1220    warpphy_setTxPower(txPower);
1221
1222    //Initialize the MAC/PHY frameworks
1223    warpmac_init();
1224   
1225    //Read Dip Switch value from FPGA board.
1226    //This value will be used as an index into the routing table for other nodes
1227    myID = warpmac_getMyId();
1228    warpmac_rightHex(myID);
1229                     
1230    //Configure the PHY and radio antenna modes
1231    warpphy_setAntennaMode(TX_ANTMODE_ALAMOUTI_ANTA, RX_ANTMODE_ALAMOUTI_ANTA);
1232//  warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA);
1233   
1234    //Set the modulation scheme use for base rate (header) symbols
1235    warpmac_setBaseRate(QPSK);
1236   
1237    //Connect the various user-level callbacks
1238    warpmac_setCallback(EVENT_PHYGOODHEADER, (void *)phyRx_goodHeader_callback);
1239    warpmac_setCallback(EVENT_PHYBADHEADER, (void *)phyRx_badHeader_callback);
1240    warpmac_setCallback(EVENT_MGMTPKT, (void *)mgmtFromNetworkLayer_callback);
1241    warpmac_setCallback(EVENT_DATAFROMNETWORK, (void *)dataFromNetworkLayer_callback);
1242    warpmac_setCallback(EVENT_UARTRX, (void *)uartRecv_callback);
1243
1244    //Set the default center frequency
1245    warpphy_setChannel(GHZ_2, chan);
1246   
1247//Set some PHY parameters
1248    //v22 default: dec2hex(round(1.00115 * 2^31))
1249//  warpphy_setPilotCFOCorrection(0x8025AEE6);
1250    //From experiments of fixed CFO=305Hz, using only pilot estimator
1251    //warpphy_setPilotCFOCorrection(0x821D7F92);
1252
1253    //round(2^32*(2.9e-5 + 5e-6))
1254    //warpphy_setCoarseCFOCorrection(146029);
1255    //round( mean(( cfo - (m(3:end-3)-cff))')*2^32 ) (from experiments)
1256//  warpphy_setCoarseCFOCorrection(30533);
1257   
1258    //Preamble/payload scaling (UFix16_13)
1259    // 2480 = 0.302
1260    // 9792 = 1.195
1261//  preambleScaling = 3072;//2480;
1262//  payloadScaling = 12288;//9792;
1263//  mimo_ofdmTx_setTxScaling(preambleScaling, payloadScaling);
1264   
1265    pktDet_corrThresh = 7000;
1266    warpphy_setLongCorrThresh(pktDet_corrThresh);
1267   
1268    //pktDet_corrWindowStart = 90-32;
1269    //pktDet_corrWindowEnd = 180+32;
1270    //longCorrCounterLoad = 245+6; //after comparing to v18
1271    //mimo_ofdmRx_setLongCorrParams( (longCorrCounterLoad&0xFF) | ((pktDet_corrWindowStart&0xFF)<<16) | ((pktDet_corrWindowEnd&0xFF)<<24));
1272    //mimo_ofdmRx_setPktDetDly(124);
1273//  ofdm_txrx_mimo_WriteReg_Rx_ControlBits(0, ofdm_txrx_mimo_ReadReg_Rx_ControlBits(0) | (LOWPREC_LONGCORR));
1274
1275
1276    energyThresh = 4000;
1277    ofdm_txrx_mimo_WriteReg_Rx_PktDet_setThresh(energyThresh);
1278
1279    //MinMag as UFix12_12
1280    //mimo_ofdmRx_setPilotCalcParams(0xFFF);
1281
1282//  FFT_offset = 10;
1283//  mimo_ofdmRx_setFFTWindowOffset(FFT_offset);
1284   
1285    //Interpreted as Fix4_0 (1=1, 2=2, 15=-1, 14=-2, 13=-3, 12=-4)
1286//  warpphy_setAntBPreambleShift(13);
1287
1288    //AF Tx scaling (UFix18_12)
1289    // 4096 = 1
1290    // 6656 = 1.625
1291    // 8192 = 2
1292    // 10240 = 2.5
1293    // 12288 = 3
1294//  afScaling = 2944;
1295//  mimo_ofdmRx_setAFTxScaling(afScaling);
1296   
1297
1298    mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | (TX_RANDOM_PAYLOAD | TX_CAPTURE_RANDOM_PAYLOAD | TX_START_D0_OUT_EN | TX_START_D1_OUT_EN));
1299
1300    //POM: Testing non-random payloads
1301    //mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | (TX_START_D0_OUT_EN | TX_START_D1_OUT_EN));
1302    //mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & ~(TX_RANDOM_PAYLOAD | TX_CAPTURE_RANDOM_PAYLOAD));
1303    //bzero((void *)warpphy_getBuffAddr(pktBuf_tx_DATA), (size_t)1500);
1304
1305    agcTargetPwr = -13; //was -13 throgh v21
1306    ofdm_AGC_SetTarget(agcTargetPwr);
1307   
1308    //Set min chanest magnitudes (UFix16_15 values)
1309    warpphy_setChanEstMinMags(0);//0x8000, 0x8000);
1310
1311    //Set AF blanking interval (set to zeros to disable)
1312    warpphy_setAFblanking(0, 0);
1313
1314    //firpm filt
1315    mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | TX_ALT_INTERPFILT);
1316   
1317    //Set MAX2829 Rx bandwidth to its minimum (helps supress out-of-band noise)
1318    WarpRadio_v1_RxLpfCornFreqCoarseAdj(0x0, RADIO2_ADDR);
1319    WarpRadio_v1_RxLpfCornFreqFineAdj(0x0, RADIO2_ADDR);
1320   
1321    numPktTypes = 1;
1322    pktTypesToTx[0] = PKTTYPE_NCDATA;
1323    curPktTypeInd = 0;
1324   
1325/*** WARPnet Measurement/Control Setup ***/
1326    groupStruct.controllerID = 0;
1327    groupStruct.controllerGrp = 0;
1328    groupStruct.access = 1;
1329    groupStruct.reserved0 = 0;
1330   
1331    //WARPnet configuration
1332    txEthPktHeader.ethType = WARPNET_ETHTYPE_NODE2SVR;
1333    txEthPktHeader.srcAddr[0]=0x00;
1334    txEthPktHeader.srcAddr[1]=0x50;
1335    txEthPktHeader.srcAddr[2]=0xC2;
1336    txEthPktHeader.srcAddr[3]=0x63;
1337    txEthPktHeader.srcAddr[4]=0x3F;
1338    txEthPktHeader.srcAddr[5]=0x80+myID;
1339
1340    coprocEthPktHeader.ethType = WARPNET_ETHTYPE_NODE2COPROC;
1341    coprocEthPktHeader.srcAddr[0]=0x00;
1342    coprocEthPktHeader.srcAddr[1]=0x50;
1343    coprocEthPktHeader.srcAddr[2]=0xC2;
1344    coprocEthPktHeader.srcAddr[3]=0x63;
1345    coprocEthPktHeader.srcAddr[4]=0x3F;
1346    coprocEthPktHeader.srcAddr[5]=0x80+myID;
1347   
1348    coprocEthPktHeader.numStructs = 1;
1349
1350
1351    //Linux eth1: 00:50:C2:63:3F:FC
1352    txEthPktHeader.dstAddr[0]=0x00;
1353    txEthPktHeader.dstAddr[1]=0x50;
1354    txEthPktHeader.dstAddr[2]=0xC2;
1355    txEthPktHeader.dstAddr[3]=0x63;
1356    txEthPktHeader.dstAddr[4]=0x3F;
1357    txEthPktHeader.dstAddr[5]=0xFC;
1358   
1359    //Linux eth1: 00:50:C2:63:3F:FC
1360    coprocEthPktHeader.dstAddr[0]=0x00;
1361    coprocEthPktHeader.dstAddr[1]=0x50;
1362    coprocEthPktHeader.dstAddr[2]=0xC2;
1363    coprocEthPktHeader.dstAddr[3]=0x63;
1364    coprocEthPktHeader.dstAddr[4]=0x3F;
1365    coprocEthPktHeader.dstAddr[5]=0xFC;
1366
1367/*
1368    //Macbook #1
1369    txEthPktHeader.dstAddr[0]=0x00;
1370    txEthPktHeader.dstAddr[1]=0x17;
1371    txEthPktHeader.dstAddr[2]=0xf2;
1372    txEthPktHeader.dstAddr[3]=0xdb;
1373    txEthPktHeader.dstAddr[4]=0x05;
1374    txEthPktHeader.dstAddr[5]=0x07;
1375
1376     //Macbook #1
1377     coprocEthPktHeader.dstAddr[0]=0x00;
1378     coprocEthPktHeader.dstAddr[1]=0x17;
1379     coprocEthPktHeader.dstAddr[2]=0xf2;
1380     coprocEthPktHeader.dstAddr[3]=0xdb;
1381     coprocEthPktHeader.dstAddr[4]=0x05;
1382     coprocEthPktHeader.dstAddr[5]=0x07;
1383 */
1384   
1385   
1386   
1387    perStruct_DF.structID = STRUCTID_OBSERVE_PER;
1388    perStruct_DF.nodeID = myID;
1389    perStruct_DF.reqNum = 0;
1390    perStruct_DF.reqType = PKTTYPE_DFDATA;
1391    perStruct_DF.numPkts_tx = 0;
1392    perStruct_DF.numPkts_rx_good = 0;
1393    perStruct_DF.numPkts_rx_goodHdrBadPyld = 0;
1394    perStruct_DF.numPkts_rx_badHdr = 0;
1395
1396    perStruct_AF.structID = STRUCTID_OBSERVE_PER;
1397    perStruct_AF.nodeID = myID;
1398    perStruct_AF.reqNum = 0;
1399    perStruct_AF.reqType = PKTTYPE_AFDATA;
1400    perStruct_AF.numPkts_tx = 0;
1401    perStruct_AF.numPkts_rx_good = 0;
1402    perStruct_AF.numPkts_rx_goodHdrBadPyld = 0;
1403    perStruct_AF.numPkts_rx_badHdr = 0;
1404   
1405    perStruct_AFGH.structID = STRUCTID_OBSERVE_PER;
1406    perStruct_AFGH.nodeID = myID;
1407    perStruct_AFGH.reqNum = 0;
1408    perStruct_AFGH.reqType = PKTTYPE_AFGHDATA;
1409    perStruct_AFGH.numPkts_tx = 0;
1410    perStruct_AFGH.numPkts_rx_good = 0;
1411    perStruct_AFGH.numPkts_rx_goodHdrBadPyld = 0;
1412    perStruct_AFGH.numPkts_rx_badHdr = 0;
1413   
1414    perStruct_DFGH.structID = STRUCTID_OBSERVE_PER;
1415    perStruct_DFGH.nodeID = myID;
1416    perStruct_DFGH.reqNum = 0;
1417    perStruct_DFGH.reqType = PKTTYPE_DFGHDATA;
1418    perStruct_DFGH.numPkts_tx = 0;
1419    perStruct_DFGH.numPkts_rx_good = 0;
1420    perStruct_DFGH.numPkts_rx_goodHdrBadPyld = 0;
1421    perStruct_DFGH.numPkts_rx_badHdr = 0;
1422
1423    perStruct_NCMHOP.structID = STRUCTID_OBSERVE_PER;
1424    perStruct_NCMHOP.nodeID = myID;
1425    perStruct_NCMHOP.reqNum = 0;
1426    perStruct_NCMHOP.reqType = PKTTYPE_NCMHOPDATA;
1427    perStruct_NCMHOP.numPkts_tx = 0;
1428    perStruct_NCMHOP.numPkts_rx_good = 0;
1429    perStruct_NCMHOP.numPkts_rx_goodHdrBadPyld = 0;
1430    perStruct_NCMHOP.numPkts_rx_badHdr = 0;
1431   
1432    perStruct_NC.structID = STRUCTID_OBSERVE_PER;
1433    perStruct_NC.nodeID = myID;
1434    perStruct_NC.reqNum = 0;
1435    perStruct_NC.reqType = PKTTYPE_NCDATA;
1436    perStruct_NC.numPkts_tx = 0;
1437    perStruct_NC.numPkts_rx_good = 0;
1438    perStruct_NC.numPkts_rx_goodHdrBadPyld = 0;
1439    perStruct_NC.numPkts_rx_badHdr = 0;
1440   
1441    perStruct_Other.structID = STRUCTID_OBSERVE_PER;
1442    perStruct_Other.nodeID = myID;
1443    perStruct_Other.reqNum = 0;
1444    perStruct_Other.reqType = PKTTYPE_INVALID;
1445    perStruct_Other.numPkts_tx = 0;
1446    perStruct_Other.numPkts_rx_good = 0;
1447    perStruct_Other.numPkts_rx_goodHdrBadPyld = 0;
1448    perStruct_Other.numPkts_rx_badHdr = 0;
1449   
1450    rxPHYdumpStruct.structID = STRUCTID_RXPHYDUMP;
1451    rxPHYdumpStruct.nodeID = myID;
1452    rxPHYdumpStruct.pktType = PKTTYPE_NCDATA;
1453    rxPHYdumpStruct.seqNum = 0;
1454   
1455    /*
1456    sleep(8);
1457    unsigned char ethernetAddr[] = {0x00,0x50,0xC2,0x63,0x3F,0x80+myID};
1458    warpnet_setMacAddr((void*)&ethernetAddr);
1459    warpnet_sendGratuitousArp(myID);
1460    */
1461   
1462    setupNodeBehaviors();
1463
1464    //Rx Buffer where the wireless PHY will write packets
1465    warpmac_setRxBuffers(&rxFrame, pktBuf_rx);
1466   
1467    //Tx buffer is where the EMAC will DMA payloads to
1468    warpmac_setEMACRxBuffer(pktBuf_emac_rx);
1469    warpmac_setPHYTxBuffer(pktBuf_tx_DATA);
1470
1471    //Listen for new packets to send (either from Ethernet or local dummy packets)
1472    warpmac_enableDataFromNetwork();
1473    warpmac_setDummyPacketMode(1);
1474   
1475    while(1){
1476        warpmac_pollPeripherals();
1477    }
1478   
1479    return;
1480}
1481
1482
1483void setupNodeBehaviors()
1484{
1485    //Disable all actors by default
1486    mimo_ofdmTxRx_setAction0(0);
1487    mimo_ofdmTxRx_setAction1(0);
1488    mimo_ofdmTxRx_setAction2(0);
1489    mimo_ofdmTxRx_setAction3(0);
1490    mimo_ofdmTxRx_setAction4(0);
1491    mimo_ofdmTxRx_setAction5(0);
1492   
1493    //Match conditions
1494    //Match condition 0: received header's destination address is me
1495    //autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_DSTADDR, 2, htons(NODEID_TO_ADDR(myID)));
1496    //mimo_ofdmTxRx_setMatch0(autoResp_matchCond);
1497   
1498    //Match condition 0: received header's relay address is me
1499    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_RLYADDR, 2, htons(NODEID_TO_ADDR(myID)));
1500    mimo_ofdmTxRx_setMatch0(autoResp_matchCond);
1501   
1502    //Match condition 1: packet type is PKTTYPE_DFDATA
1503    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_TYPE, 1, PKTTYPE_DFDATA);
1504    mimo_ofdmTxRx_setMatch1(autoResp_matchCond);
1505   
1506    //Match condition 2: packet type is PKTTYPE_AFDATA
1507    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_TYPE, 1, PKTTYPE_AFDATA);
1508    mimo_ofdmTxRx_setMatch2(autoResp_matchCond);
1509
1510    //Match condition 3: packet type is PKTTYPE_AFGHDATA
1511    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_TYPE, 1, PKTTYPE_AFGHDATA);
1512    mimo_ofdmTxRx_setMatch3(autoResp_matchCond);
1513   
1514    //Match condition 4: packet type is PKTTYPE_DFGHDATA
1515    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_TYPE, 1, PKTTYPE_DFGHDATA);
1516    mimo_ofdmTxRx_setMatch4(autoResp_matchCond);
1517
1518    //Match condition 5: packet type is REQ_NCMHOPDATA
1519    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_TYPE, 1, PKTTYPE_NCMHOPDATA);
1520    mimo_ofdmTxRx_setMatch5(autoResp_matchCond);
1521   
1522    //Set Tx delays (src-reTx, autoRespExtra, txStart outputs)
1523    mimo_ofdmTx_setDelays(autoRespDelay_SrcReTx, 0, pktDetBypass_txStartDly);
1524
1525    if(coopTesting) {
1526        if(myID == ID_SRC) {
1527            //Enable auto-TwoTx mode, so the source transmits every packet twice back-to-back
1528            mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | (TX_AUTO_TWOTX_EN));
1529
1530            //Disable packet detection at the src; it never receives packets
1531            ofdm_txrx_mimo_WriteReg_Rx_PktDet_ignoreDet(1);
1532        }
1533        else if(myID == ID_RLY) {
1534            //Relay transmits after receiving DATA packet from src
1535            //autoResp_action_relayTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_rx, (PHY_AUTORESPONSE_ACT_SWAP_ANT | PHY_AUTORESPONSE_ACT_USE_PRECFO), autoRespDelay_RlyTx_DF, (REQ_RLY_ME | REQ_DFDATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
1536            //autoResp_action_relayTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_rx, (0), autoRespDelay_RlyTx_DF, (REQ_RLY_ME | REQ_DFDATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
1537            autoResp_action_relayTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_rx, (PHY_AUTORESPONSE_ACT_USE_PRECFO), autoRespDelay_RlyTx_DF, (REQ_RLY_ME | REQ_DFDATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
1538            mimo_ofdmTxRx_setAction0(autoResp_action_relayTx);
1539
1540            autoResp_action_relayTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_AF, (0), autoRespDelay_RlyTx_AF, (REQ_RLY_ME | REQ_AFDATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
1541            mimo_ofdmTxRx_setAction1(autoResp_action_relayTx);
1542
1543            autoResp_action_relayTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_AF, (0), autoRespDelay_RlyTx_AF, (REQ_RLY_ME | REQ_AFGHDATA | PHY_AUTORESPONSE_REQ_GOODHDR));
1544            mimo_ofdmTxRx_setAction2(autoResp_action_relayTx);
1545
1546            autoResp_action_relayTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_rx, (PHY_AUTORESPONSE_ACT_USE_PRECFO | PHY_AUTORESPONSE_ACT_RETX_CRC), autoRespDelay_RlyTx_DF, (REQ_RLY_ME | REQ_DFGHDATA | PHY_AUTORESPONSE_REQ_GOODHDR));
1547            //POM: temporarily refdefining DFGH to be DF w/out prespin!
1548//          autoResp_action_relayTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_rx, (0), autoRespDelay_RlyTx_DF, (REQ_RLY_ME | REQ_DFGHDATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
1549            mimo_ofdmTxRx_setAction3(autoResp_action_relayTx);
1550           
1551            autoResp_action_relayTx = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_rx, (0), autoRespDelay_RlyTx_DF, (REQ_RLY_ME | REQ_NCMHOPDATA | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
1552            mimo_ofdmTxRx_setAction4(autoResp_action_relayTx);
1553           
1554            warpphy_AFrecordEnable(1);
1555        }
1556        else if(myID == ID_DST)
1557        {
1558        }
1559    } //END if(coopTesting)
1560
1561    if(nonCoopTesting) {
1562        if(myID == ID_SRC)
1563        {
1564            mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() & ~(TX_AUTO_TWOTX_EN));
1565
1566            //Disable packet detection at the src; it never receives packets
1567            ofdm_txrx_mimo_WriteReg_Rx_PktDet_ignoreDet(1);
1568        }
1569        else if(myID == ID_RLY)
1570        {
1571            mimo_ofdmTxRx_setAction0(0);
1572            mimo_ofdmTxRx_setAction1(0);
1573            mimo_ofdmTxRx_setAction2(0);
1574        }
1575        else if(myID == ID_DST)
1576        {
1577        }
1578    } //END if(nonCoopTesting)
1579    return;
1580}
1581
1582void setDACinterp(unsigned int mode, unsigned int radios) {
1583    unsigned int divreg;
1584   
1585
1586    divreg = RADIO_CONTROLLER_mReadSlaveReg6(XPAR_RADIO_CONTROLLER_0_BASEADDR);
1587    RADIO_CONTROLLER_mWriteSlaveReg5((volatile)XPAR_RADIO_CONTROLLER_0_BASEADDR, 0x3410);           // Set the value of the Control Register to 0x00003410 for DACs
1588    RADIO_CONTROLLER_mWriteSlaveReg6((volatile)XPAR_RADIO_CONTROLLER_0_BASEADDR, 0x00000001);       // Set the value for the Divider Register to 0x00000001
1589   
1590    RADIO_CONTROLLER_mWriteSlaveReg7((volatile)XPAR_RADIO_CONTROLLER_0_BASEADDR, (SLAVEMASKDAC & radios));      // Select the dacs that need to be affected
1591
1592    transmitdac( (0x0104 | ( (mode & 0x3)<<6) ) );
1593
1594    transmitdac( (0x0300 | ( (mode & 0x30)>>4)) );
1595
1596    if((mode&0x33) > 0) {
1597        //Enable the AD9777 PLL
1598        transmitdac(0x0480);
1599    } else {
1600        //Disable the AD9777 PLL
1601        transmitdac(0x0400);
1602    }
1603
1604    transmitdac(0x060F);
1605    transmitdac(0x0A0F);
1606   
1607    RADIO_CONTROLLER_mWriteSlaveReg5((volatile)XPAR_RADIO_CONTROLLER_0_BASEADDR, 0x3412);           // Set the value of the Control Register to 0x00003412 for Radio
1608    RADIO_CONTROLLER_mWriteSlaveReg6((volatile)XPAR_RADIO_CONTROLLER_0_BASEADDR, divreg);       // Set the value for the Divider Register to 0x00000000
1609
1610    return;
1611}
Note: See TracBrowser for help on using the repository browser.