source: ResearchApps/MAC/WARPNET_EXAMPLE/warpnet_example.c

Last change on this file was 1817, checked in by murphpo, 12 years ago
  • Property svn:executable set to *
File size: 22.1 KB
Line 
1/*! \file warpnet_example.c
2 \brief Example top-level code for using WARPnet to characterize MAC/PHY performance
3
4 @version 18.0_WARPv3_Testing
5 @author Chris Hunter & Patrick Murphy
6
7*/
8
9#include "xparameters.h"
10#include "warpmac.h"
11#include "warpphy.h"
12#include "warpnet.h"
13#include "warpnet_example.h"
14#include "string.h"
15#include "stdio.h"
16
17//Lower level includes, for debug/development
18#include "util/ofdm_txrx_mimo_regMacros.h"
19#include "util/ofdm_agc_mimo_regMacros.h"
20#include "warp_hw_ver.h"
21
22///Buffer to hold received packet
23Macframe rxFrame;
24
25unsigned char pktBuf_rx;
26unsigned char pktBuf_tx;
27unsigned char pktBuf_emac_rx;
28
29u32 pktGen_length, pktGen_period;
30unsigned char chan;
31unsigned char pktFullRate;
32unsigned char pktCodeRate;
33unsigned char txPower;
34
35unsigned char reportBERviaWarpnet;
36
37unsigned short seqNum;
38
39void processPHYControl(warpnetPHYctrl* phyCtrlStruct);
40
41///Struct for reporting PER via WARPnet
42warpnetObservePER perStruct;
43
44///Template Ethernet headers used to construct outgoing WARPnet packets
45warpnetEthernetPktHeader txEthPktHeader;
46warpnetEthernetPktHeader coprocEthPktHeader;
47
48///Template WARPnet server/group struct, for outgoing WARPnet packets
49warpnetControllerGroup groupStruct;
50
51///ID of this node
52unsigned short int myID;
53
54///@brief Callback for the reception of data frames from the higher network layer
55///
56///This function is called by the ethernet MAC drivers
57///when a packet is available to send. This function fills
58///the Macframe transmit buffer with the packet and sends
59///it over the OFDM link.
60///@param length Length, in bytes, of received Ethernet frame
61///@param payload address of first byte in Ethernet payload.
62void dataFromNetworkLayer_callback(Xuint32 length, char* payload)
63{
64
65    void* txPktPtr;
66    //Buffer for holding a packet-to-xmit
67    Macframe txFrame;
68    //Set the length field in the header
69    txFrame.header.length = length;
70    //Set the addresses
71    txFrame.header.srcAddr = (unsigned short)myID;
72    txFrame.header.destAddr = (unsigned short)((myID+1)%2);
73    //Set the modulation scheme for the packet's full-rate symbols
74    txFrame.header.fullRate = pktFullRate;
75    //Set the payload coding rate
76    txFrame.header.codeRate = pktCodeRate;
77
78    //Increment the gloabl sequence number, then copy it to the outgoing header
79    seqNum++;
80    txFrame.header.seqNum = seqNum;
81
82    //Copy the header over to packet buffer 1
83    warpmac_prepPhyForXmit(&txFrame, pktBuf_tx);
84    //Send packet buffer pktBuf_tx
85    warpmac_startPhyXmit(pktBuf_tx);
86    //Wait for it to finish and enable the receiver
87    warpmac_finishPhyXmit();
88
89    perStruct.numPkts_tx++;
90
91    if(reportBERviaWarpnet) {
92        //Send a copy of the just-transmitted packet to the BER calculating app
93        //BER packets are built from:
94        // Ethernet header [0:15]
95        // MAC/PHY header [0:23] generated above
96        // Actual transmitted payload (randomly generated and recorded in the PHY) [0:length-1]
97       
98        coprocEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(phyHeader) + length;
99        coprocEthPktHeader.ethType = WARPNET_ETHTYPE_NODE2BER; 
100       
101        txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2COPROC_PKTBUFFINDEX);
102        memcpy(txPktPtr, &(coprocEthPktHeader), sizeof(warpnetEthernetPktHeader));
103        txPktPtr += sizeof(warpnetEthernetPktHeader);
104        memcpy(txPktPtr, (void*)&(txFrame.header), sizeof(phyHeader));
105        txPktPtr += sizeof(phyHeader);
106       
107        memcpy(txPktPtr, (void *)(warpphy_getBuffAddr(pktBuf_tx)+sizeof(phyHeader)), length);
108       
109        warpmac_prepPktToNetwork((void *)warpphy_getBuffAddr(WARPNET_NODE2COPROC_PKTBUFFINDEX), coprocEthPktHeader.pktLength);
110        warpmac_startPktToNetwork(coprocEthPktHeader.pktLength);
111    }
112}
113
114void mgmtFromNetworkLayer_callback(Xuint32 length, char* payload) {
115   
116    void* rxPktPtr;
117    void* txPktPtr;
118   
119    int i, numRxStructs;
120    unsigned char rxSeqNum, theStructID;
121   
122    //Typed pointers for interpreting received structs
123    warpnetEthernetPktHeader* pktHeader;
124    warpnetControllerGroup* groupStructCopy;
125    warpnetCommand* commandStruct;
126    warpnetControl* controlStruct;
127    warpnetPHYctrl* phyCtrlStruct;
128
129    warpnetPERreq* perReqPtr;
130   
131    //Local ACK struct, used to send responses to the server
132    warpnetAck ackStruct;
133   
134    //Interpret the received bytes as an Ethernet packet
135    pktHeader = (warpnetEthernetPktHeader*)payload;
136   
137    if((pktHeader->ethType) != WARPNET_ETHTYPE_SVR2NODE) {
138        //Should never happen; all management packets are type WARPNET_ETHTYPE_SVR2NODE
139        return;
140    }
141   
142    numRxStructs = pktHeader->numStructs;
143    rxSeqNum = pktHeader->seqNum;
144   
145    //Initialize the rx pointer to the first byte past the Ethernet header
146    rxPktPtr = (void*)(payload + sizeof(warpnetEthernetPktHeader));
147   
148    //Iterate over each pair of warpnetControllerGroup / otherStruct in the server message
149    for(i=0; i<numRxStructs; i++) {
150       
151        if( ( ((int)rxPktPtr) - ((int)payload) ) >= length) {
152            xil_printf("Error! Mgmt pktLength too short for numStructs\r\n");
153            return;
154        }
155       
156        //Alternate structs (starting with the first) are always warpnetControllerGroup
157        groupStructCopy = (warpnetControllerGroup*)rxPktPtr;
158        rxPktPtr += sizeof(warpnetControllerGroup);
159       
160        //Extract the first byte of the actual struct and interpret as the structID
161        theStructID = *( (unsigned char *)rxPktPtr );
162        //xil_printf("Mgmt Pkt: StructID=0x%x\r\n", theStructID);
163       
164        switch(theStructID)
165        {
166            case STRUCTID_COMMAND:
167                commandStruct = (warpnetCommand*)rxPktPtr;
168                rxPktPtr += sizeof(warpnetCommand);
169               
170                if((commandStruct->nodeID) == myID) {
171                   
172                    //Send an ACK struct back to the server
173                    ackStruct.structID = STRUCTID_COMMAND_ACK;
174                    ackStruct.nodeID = myID;
175                    ackStruct.cmdID = commandStruct->cmdID;
176                   
177                    txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetControllerGroup) + sizeof(warpnetAck);
178                    txEthPktHeader.numStructs = 1;
179                   
180                    //Construct the outgoing Ethernet packet
181                    txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
182                    memcpy(txPktPtr, (void *)&(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
183                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader), (void *)groupStructCopy, sizeof(warpnetControllerGroup));
184                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader)+sizeof(warpnetControllerGroup), (void *)&(ackStruct), sizeof(warpnetAck));
185                   
186                    //Set the Ethernet packet
187                    warpmac_prepPktToNetwork(txPktPtr, txEthPktHeader.pktLength);
188                    warpmac_startPktToNetwork(txEthPktHeader.pktLength);
189                   
190                    //Process the received struct
191                    processCommand(commandStruct);
192                }
193                break;
194               
195            case STRUCTID_CONTROL:
196                controlStruct = (warpnetControl*)rxPktPtr;
197                rxPktPtr += sizeof(warpnetControl);
198               
199                if((controlStruct->nodeID) == myID) {
200
201                    //Send an ACK struct back to the server
202                    ackStruct.structID = STRUCTID_CONTROL_ACK;
203                    ackStruct.nodeID = myID;
204                   
205                    txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetControllerGroup) + sizeof(warpnetAck);
206                    txEthPktHeader.numStructs = 1;
207                   
208                    //Construct the outgoing Ethernet packet
209                    txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
210                    memcpy(txPktPtr, (void *)&(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
211                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader), (void *)groupStructCopy, sizeof(warpnetControllerGroup));
212                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader)+sizeof(warpnetControllerGroup), (void *)&(ackStruct), sizeof(warpnetAck));
213                   
214                    //Set the Ethernet packet
215                    warpmac_prepPktToNetwork(txPktPtr, txEthPktHeader.pktLength);
216                    warpmac_startPktToNetwork(txEthPktHeader.pktLength);
217                   
218                    //Process the received struct
219                    processControl(controlStruct);
220                }
221                break;
222            case STRUCTID_OBSERVE_PER_REQ:
223                perReqPtr = (warpnetPERreq*)rxPktPtr;
224                rxPktPtr += sizeof(warpnetPERreq);
225               
226                if((perReqPtr->nodeID) == myID) {
227                   
228                    //Copy over the request ID to the PER struct (this allows the client to confirm it got the right PER struct reply)
229                    perStruct.reqNum = (unsigned char)perReqPtr->reqNum;
230                   
231                    txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetControllerGroup) + sizeof(warpnetObservePER);
232                    txEthPktHeader.numStructs = 1;
233                   
234                    //Construct the outgoing Ethernet packet
235                    txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
236                    memcpy(txPktPtr, (void *)&(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
237                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader), (void *)groupStructCopy, sizeof(warpnetControllerGroup));
238                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader)+sizeof(warpnetControllerGroup), (void *)&perStruct, sizeof(warpnetObservePER));
239                   
240                    //Set the Ethernet packet
241                    warpmac_prepPktToNetwork(txPktPtr, txEthPktHeader.pktLength);
242                    warpmac_startPktToNetwork(txEthPktHeader.pktLength);
243                }
244                break;
245            case STRUCTID_PHYCTRL:
246                phyCtrlStruct = (warpnetPHYctrl*)rxPktPtr;
247                rxPktPtr += sizeof(warpnetPHYctrl);
248
249                if((phyCtrlStruct->nodeID) == myID) {
250                    //Send an ACK struct back to the server
251                    ackStruct.structID = STRUCTID_PHYCTRL_ACK;
252                    ackStruct.nodeID = myID;
253
254                    txEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(warpnetControllerGroup) + sizeof(warpnetAck);
255                    txEthPktHeader.numStructs = 1;
256
257                    txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2SVR_PKTBUFFINDEX);
258                    memcpy(txPktPtr, (void *)&(txEthPktHeader), sizeof(warpnetEthernetPktHeader));
259                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader), (void *)groupStructCopy, sizeof(warpnetControllerGroup));
260                    memcpy(txPktPtr+sizeof(warpnetEthernetPktHeader)+sizeof(warpnetControllerGroup), (void *)&(ackStruct), sizeof(warpnetAck));
261
262                    warpmac_prepPktToNetwork(txPktPtr, txEthPktHeader.pktLength);
263                    warpmac_startPktToNetwork(txEthPktHeader.pktLength);
264
265                    //Process the received struct
266                    processPHYControl(phyCtrlStruct);
267                }
268                break;
269               
270            default:
271                //Unrecognized structID; do nothing
272                //xil_printf("Unknown structID: 0x%x\r\n", theStructID);
273                break;
274        }//END switch(theStructID)
275    }//END for(0...numStructs-1)
276   
277    return;
278}
279
280void processCommand(warpnetCommand* commandStruct) {
281    switch(commandStruct->cmdID) {
282        case COMMANDID_STARTTRIAL:
283            warpmac_startPacketGeneration(pktGen_length, pktGen_period);
284            break;
285
286        case COMMANDID_STOPTRIAL:
287            warpmac_stopPacketGeneration();
288            break;
289
290        case COMMANDID_RESET_PER:
291            perStruct.numPkts_tx = 0;
292            perStruct.numPkts_rx_good = 0;
293            perStruct.numPkts_rx_goodHdrBadPyld = 0;
294            perStruct.numPkts_rx_badHdr = 0;
295            break;
296
297        case COMMANDID_ENABLE_BER_TESTING:
298            reportBERviaWarpnet = 1;
299            break;
300
301        case COMMANDID_DISABLE_BER_TESTING:
302            reportBERviaWarpnet = 0;
303            break;
304           
305        default:
306            //Unknown command; do nothing
307            xil_printf("processCommand: unknown command: 0x%x\r\n", commandStruct->cmdID);
308            break;
309    }
310   
311    return;
312}
313
314void processControl(warpnetControl* controlStruct) {
315    unsigned char newMod, newCode;
316
317    newMod = ((controlStruct->modOrderPayload) & 0xF);
318    newCode = ((controlStruct->codeRatePayload) & 0xF);
319
320    pktGen_length = (controlStruct->pktGen_length);
321    pktGen_period = (controlStruct->pktGen_period);
322
323    txPower = ((controlStruct->txPower) & 0x3F);
324    warpphy_setTxPower(txPower);
325   
326    chan = controlStruct->channel;
327
328    xil_printf("Ctrl struct: mod=%d, code=%d, hdr=%d, pktLen=%d, pktPeriod=%d, chan=%d\n", newMod, newCode, controlStruct->modOrderHeader, pktGen_length, pktGen_period, chan);
329
330    switch(newMod) {
331        case 1: pktFullRate = HDR_FULLRATE_BPSK; break;
332        case 2: pktFullRate = HDR_FULLRATE_QPSK; break;
333        case 4: pktFullRate = HDR_FULLRATE_QAM_16; break;
334        case 6: pktFullRate = HDR_FULLRATE_QAM_64; break;
335        default: pktFullRate = HDR_FULLRATE_QPSK; break;
336    }
337   
338    switch(newCode) {
339        case HDR_CODE_RATE_12: pktCodeRate = HDR_CODE_RATE_12; break;
340        case HDR_CODE_RATE_23: pktCodeRate = HDR_CODE_RATE_23; break;
341        case HDR_CODE_RATE_34: pktCodeRate = HDR_CODE_RATE_34; break;
342        case HDR_CODE_RATE_NONE: pktCodeRate = HDR_CODE_RATE_NONE; break;
343        default: pktCodeRate = HDR_CODE_RATE_NONE; break;
344    }
345   
346    switch(controlStruct->modOrderHeader) {
347        case 1: warpmac_setBaseRate(BPSK); break;
348        case 2: warpmac_setBaseRate(QPSK); break;
349        default: warpmac_setBaseRate(QPSK); break;
350    }
351   
352    warpphy_setChannel(GHZ_2, chan);
353}
354
355///@brief Callback for the reception of bad wireless headers
356///
357///@param packet Pointer to received Macframe
358void phyRx_badHeader_callback()
359{
360    u32 gains;
361    gains = ofdm_txrx_mimo_ReadReg_Rx_Gains(0);
362    warpmac_leftHex( (gains>>5) & 0x3);
363    //xil_printf("BH %5d %2d %1d\n", ofdm_txrx_mimo_ReadReg_Rx_PktDet_midPktRSSI_antA(), gains&0x1F, (gains>>5)&0x3);
364
365    perStruct.numPkts_rx_badHdr++;
366
367    warpmac_incrementLEDLow();
368}
369
370///@brief Callback for the reception of good wireless headers
371///
372///This function then polls the PHY to determine if the entire packet passes checksum
373///thereby triggering the transmission of the received data over Ethernet.
374///@param packet Pointer to received Macframe
375int phyRx_goodHeader_callback(Macframe* packet)
376{
377    u32 gains;
378    gains = ofdm_txrx_mimo_ReadReg_Rx_Gains(0);
379    warpmac_leftHex( (gains>>5) & 0x3);
380
381    //xil_printf("GH %5d %2d %1d\n", ofdm_txrx_mimo_ReadReg_Rx_PktDet_midPktRSSI_antA(), gains&0x1F, (gains>>5)&0x3);
382
383    void* txPktPtr;
384
385    //Initialize the Rx pkt state variable
386    unsigned char state = PHYRXSTATUS_INCOMPLETE;
387
388    if(reportBERviaWarpnet) {
389        //Send a copy of the just-received packet to the BER calculating app
390        //BER packets are built from:
391        // Ethernet header [0:15]
392        // MAC/PHY header [0:23] generated above
393        // Actual transmitted payload (randomly generated and recorded in the PHY) [0:length-1]
394        coprocEthPktHeader.pktLength = sizeof(warpnetEthernetPktHeader) + sizeof(phyHeader) + (packet->header.length);
395        coprocEthPktHeader.ethType = WARPNET_ETHTYPE_NODE2BER; 
396       
397        txPktPtr = (void *)warpphy_getBuffAddr(WARPNET_NODE2COPROC_PKTBUFFINDEX);
398        memcpy(txPktPtr, &(coprocEthPktHeader), sizeof(warpnetEthernetPktHeader));
399        txPktPtr += sizeof(warpnetEthernetPktHeader);
400        memcpy(txPktPtr, (void*)&(packet->header), sizeof(phyHeader));
401        txPktPtr += sizeof(phyHeader);
402    }
403   
404    //Poll the PHY; blocks until the PHY declares the payload good or bad
405    state = warpmac_finishPhyRecv();
406
407    if(state & PHYRXSTATUS_GOOD)
408    {
409        //We're in dummy packet mode, so we shouldn't copy the received packet to Etherent
410       
411        //Toggle the top user LEDs
412        warpmac_incrementLEDHigh();
413       
414        perStruct.numPkts_rx_good++;
415    }
416
417    if(state & PHYRXSTATUS_BAD)
418    {
419        //If the received packet has errors, drop it (i.e. don't send it via Ethernet)
420
421        //Toggle the bottom user LEDs
422        warpmac_incrementLEDLow();
423
424        perStruct.numPkts_rx_goodHdrBadPyld++;
425    }
426
427    //Send the received packet for BER processing
428    if(reportBERviaWarpnet) {
429        memcpy(txPktPtr, (void *)(warpphy_getBuffAddr(pktBuf_rx)+sizeof(phyHeader)), packet->header.length);
430       
431        warpmac_prepPktToNetwork((void *)warpphy_getBuffAddr(WARPNET_NODE2COPROC_PKTBUFFINDEX), coprocEthPktHeader.pktLength);
432        warpmac_startPktToNetwork(coprocEthPktHeader.pktLength);
433    }
434
435    //Return 0, indicating this function did not clear the PHY status bits; WARPMAC will handle this
436    return 0;
437}
438
439///@brief Main function
440///
441///This function configures MAC parameters, enables the underlying frameworks, and then loops forever.
442int main()
443{
444    xil_printf("\fWARPNET Example v18.0\r\n");
445
446
447    //Assign Tx/Rx to packet buffers in the PHY
448    pktBuf_rx = 1;
449    pktBuf_tx = 2;
450    pktBuf_emac_rx = 3;
451   
452    //Set the center frequency
453    chan = 3;
454   
455    //Initialize the sequence number for outgoing packets
456    seqNum = 0;
457   
458    //Set the default full-rate modulation rate
459    pktFullRate = HDR_FULLRATE_QPSK;
460    pktCodeRate = HDR_CODE_RATE_34;
461   
462    //Initialize the framework
463    // This function sets safe defaults for many parameters in the MAC/PHY frameworks
464    // Many of these can be changed with other warpmac_ and warpphy_ calls
465    //  or by customizing the warpmac.c/warpphy.c source
466    warpmac_init();
467
468    //Read Dip Switch value from FPGA board.
469    //This value will be used as an index into the routing table for other nodes
470    myID = (unsigned short int)warpmac_getMyId();
471    warpmac_rightHex(myID);
472   
473    //Choose the antnenna mode
474    warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA);
475    //warpphy_setAntennaMode(TX_ANTMODE_ALAMOUTI_ANTA, RX_ANTMODE_ALAMOUTI_ANTA);
476    //warpphy_setAntennaMode(TX_ANTMODE_MULTPLX, RX_ANTMODE_MULTPLX);
477
478    //Rx buffer is where the EMAC will DMA Wireless payloads from
479    warpmac_setRxBuffers(&rxFrame, pktBuf_rx);
480
481    //Tx buffer is where the EMAC will DMA Ethernet payloads to
482    warpmac_setEMACRxBuffer(pktBuf_emac_rx);
483    warpmac_setPHYTxBuffer(pktBuf_tx);
484
485    //Connect the various user-level callbacks
486    warpmac_setCallback(EVENT_DATAFROMNETWORK, (void *)dataFromNetworkLayer_callback);
487    warpmac_setCallback(EVENT_MGMTPKT, (void *)mgmtFromNetworkLayer_callback);
488    warpmac_setCallback(EVENT_PHYGOODHEADER, (void *)phyRx_goodHeader_callback);
489    warpmac_setCallback(EVENT_PHYBADHEADER, (void *)phyRx_badHeader_callback);
490
491#ifdef WARP_HW_VER_v3
492    //Set the OFDM Rx detection thresholds
493    warpphy_setCarrierSenseThresh(4000); //Carrier sense thresh (in [0,16368])
494    warpphy_setEnergyDetThresh(6500);       //Min RSSI (in [0,16368])
495    warpphy_setAutoCorrDetParams(50, 20);   //Min auto-correlation (UFix8_7) and min energy (UFix16_8)
496    warpphy_setLongCorrThresh(10000);       //Min cross-correlation (in [0,45e3])
497
498    //Set the default Tx gain (in [0,63])
499    warpphy_setTxPower(50);
500#else
501    //Set the OFDM Rx detection thresholds (copied from OFDM ref des v17 for now)
502    warpphy_setCarrierSenseThresh(12000); //Carrier sense thresh (in [0,16368])
503    warpphy_setEnergyDetThresh(7000);       //Min RSSI (in [0,16368])
504    warpphy_setAutoCorrDetParams(90, 20);   //Min auto-correlation (UFix8_7) and min energy (UFix16_8)
505    warpphy_setLongCorrThresh(8000);        //Min cross-correlation (in [0,45e3])
506
507    //Set the default Tx gain (in [0,63])
508    warpphy_setTxPower(55);
509#endif
510
511    //Set the default center frequency
512    warpphy_setChannel(GHZ_2, 11);
513
514    //Enable dummy packet mode; data packets will only be generated locally
515    warpmac_setDummyPacketMode(1);
516
517    //Set safe default dummy packet length/intervals; WARPnet will override these per-experiment
518    pktGen_length = 1412;
519    pktGen_period = 10000;
520
521    //Enable the OFDM Tx random payload generator (so locally generated packets have some non-zero payloads)
522    mimo_ofdmTx_setControlBits(mimo_ofdmTx_getOptions() | (TX_RANDOM_PAYLOAD | TX_CAPTURE_RANDOM_PAYLOAD));
523
524    //Listen for new packets to send (either from Ethernet or local dummy packets)
525    warpmac_enableDataFromNetwork();
526   
527    /*** WARPnet Measurement/Control Setup ***/
528    //Fill in the server/group struct with sane defaults
529    groupStruct.controllerID = 0;
530    groupStruct.controllerGrp = 0;
531    groupStruct.access = 1;
532    groupStruct.reserved0 = 0;
533   
534    perStruct.structID = STRUCTID_OBSERVE_PER;
535    perStruct.nodeID = myID;
536    perStruct.reqNum = 0;
537    perStruct.reqType = 0;
538    perStruct.numPkts_tx = 0;
539    perStruct.numPkts_rx_good = 0;
540    perStruct.numPkts_rx_goodHdrBadPyld = 0;
541    perStruct.numPkts_rx_badHdr = 0;
542   
543    //Disable reporting of packets for BER testing (WARPnet may enable at runtime)
544    reportBERviaWarpnet = 0;
545
546    //Fill in the Ethernet packet header templates
547    txEthPktHeader.ethType = WARPNET_ETHTYPE_NODE2SVR;
548    txEthPktHeader.srcAddr[0]=0x00;
549    txEthPktHeader.srcAddr[1]=0x50;
550    txEthPktHeader.srcAddr[2]=0xC2;
551    txEthPktHeader.srcAddr[3]=0x63;
552    txEthPktHeader.srcAddr[4]=0x3F;
553    txEthPktHeader.srcAddr[5]=0x80+myID;
554   
555    /****************************** NOTE ********************************/
556    /* You should fill in the MAC address of your WARPnet server here! */
557    /*******************************************************************/
558    txEthPktHeader.dstAddr[0]=0xff;
559    txEthPktHeader.dstAddr[1]=0xff;
560    txEthPktHeader.dstAddr[2]=0xff;
561    txEthPktHeader.dstAddr[3]=0xff;
562    txEthPktHeader.dstAddr[4]=0xff;
563    txEthPktHeader.dstAddr[5]=0xff;
564    txEthPktHeader.numStructs = 1;
565
566    coprocEthPktHeader.ethType = WARPNET_ETHTYPE_NODE2BER;
567    coprocEthPktHeader.srcAddr[0]=0x00;
568    coprocEthPktHeader.srcAddr[1]=0x50;
569    coprocEthPktHeader.srcAddr[2]=0xC2;
570    coprocEthPktHeader.srcAddr[3]=0x63;
571    coprocEthPktHeader.srcAddr[4]=0x3F;
572    coprocEthPktHeader.srcAddr[5]=0x80+myID;
573
574    /****************************** NOTE ********************************/
575    /* You should fill in the MAC address of your WARPnet server here! */
576    /*******************************************************************/
577    coprocEthPktHeader.dstAddr[0]=0xff;
578    coprocEthPktHeader.dstAddr[1]=0xff;
579    coprocEthPktHeader.dstAddr[2]=0xff;
580    coprocEthPktHeader.dstAddr[3]=0xff;
581    coprocEthPktHeader.dstAddr[4]=0xff;
582    coprocEthPktHeader.dstAddr[5]=0xff;
583    coprocEthPktHeader.numStructs = 1;
584   
585    while(1)
586    {
587        //Poll the timer, PHY and user I/O forever; actual processing will happen via callbacks above
588        warpmac_pollPeripherals();
589    }
590
591    return 0;
592}
593
594void processPHYControl(warpnetPHYctrl* phyCtrlStruct) {
595    //Interpret the PHY control parameters
596    //PHYCtrol params:
597    //param0: pktDet: AutoCorr corr thresh
598    //param1: pktDet: AutoCorr energy thresh
599    //param2: pktDet: RSSI thresh
600    //param3: Long Corr: Corr thresh
601    //param4: AGC: target output power
602    //param5: AGC: RSSI thresholds (3 8-bit values)
603    //param6: AGC: initial BB gain
604    //param7:
605    //param8:
606    //param9:
607
608    //param0 / param1: (corr thresh as UFix8_7, power thresh as UFix16_8)
609    if((phyCtrlStruct->param0) > 0 && (phyCtrlStruct->param1) > 0)
610        warpphy_setAutoCorrDetParams(phyCtrlStruct->param0, phyCtrlStruct->param1);
611
612    //param2: RSSI thresh as UFix16_0 (really UFix14_0, since it thresholds sum(RSSI(T-0:T-15))
613    if((phyCtrlStruct->param2) > 0)
614        warpphy_setEnergyDetThresh(phyCtrlStruct->param2);
615
616    //param3: Min cross-correlation (in [0,45e3])
617    if((phyCtrlStruct->param3) > 0)
618        warpphy_setLongCorrThresh(phyCtrlStruct->param3);
619
620    //param4: AGC target output power, as Fix8_0
621    if((phyCtrlStruct->param4) > 0)
622        ofdm_AGC_SetTarget((signed char)(phyCtrlStruct->param4));
623
624    //param5: AGC RSSI-in-dBm thresholds, as 3-byte value (AGC_THRESH_1, AGC_THRESH_2, AGC_THRESH_3)
625    //Each byte is UFix8_0 reinterpreted in hardware as Fix8_0 (so -57dB = 0xC7 (dec2hex(256-57)))
626    if((phyCtrlStruct->param5) > 0)
627        OFDM_AGC_MIMO_WriteReg_Thresholds(0, phyCtrlStruct->param5);
628
629    //param6: AGC RSSI-in-dBm thresholds, as 3-byte value (AGC_THRESH_1, AGC_THRESH_2, AGC_THRESH_3)
630    //Each byte is UFix8_0 reinterpreted in hardware as Fix8_0 (so -57dB = 0xC7 (dec2hex(256-57)))
631    if((phyCtrlStruct->param6) > 0)
632        OFDM_AGC_MIMO_WriteReg_GBB_init(0, (phyCtrlStruct->param6));
633
634    //param7: AGC DCO timing- 4 bytes, each 8-bit counter value threshold: [apply DCO, capt64 capt48, X]
635    // default from warphpy.c: 0x463C2C03 (current) or 0x46403003 (old)
636    if((phyCtrlStruct->param7) > 0)
637        OFDM_AGC_MIMO_WriteReg_DCO_Timing(0, (phyCtrlStruct->param7)); //
638
639
640    return;
641}
Note: See TracBrowser for help on using the repository browser.