source: ResearchApps/MAC/CSMAMAC/csmaMac.c

Last change on this file was 1890, checked in by murphpo, 10 years ago
  • Property svn:eol-style set to native
File size: 20.2 KB
Line 
1/*! \file csmaMac.c
2 \brief Carrier-Sensing Random Access MAC.
3
4 @version 18.0
5 @author Chris Hunter and Patrick Murphy
6
7 The csmaMac is a modified ALOHA MAC that
8 serves as an example for novel MAC
9 development. Nodes transmit whenever
10 they have information to transmit, and only
11 move on to the next packet once the original
12 transmit is acknowledged (ACKed). If no ACK
13 is received, a collision is inferred and the
14 packet is re-transmitted.
15
16 By default, the MAC also implements carrier-
17 sensing multiple-access with collision-
18 avoidance (CSMA-CA). This functionality is
19 built into hardware peripherals in the project
20 so very little software state is affected.
21
22 In its current state, the project acts as
23 a true Ethernet MAC-level wireless bridge.
24 Any Ethernet activity that appears on one
25 WARP will be sent to another via the custom
26 wireless link.
27
28 Also, the current versions supports hardware-triggered
29 ACK transmissions. This reduces the turn-around time
30 as well as reduces the jitter on the start time of the ACK
31 relative to the start time of the preceding DATA.
32
33 */
34#include "warpmac.h"
35#include "warpphy.h"
36#include "csmaMac.h"
37#include "util/ascii_characters.h"
38#include "util/ofdm_txrx_mimo_regMacros.h"
39#include "util/ofdm_agc_mimo_regMacros.h"
40
41#include "stdio.h"
42#include "xparameters.h"
43#include "warp_hw_ver.h"
44
45Macframe templatePkt;
46
47unsigned int autoResp_matchCond;
48unsigned int autoResp_action;
49unsigned char pktBuf_tx_ACK;
50unsigned char pktBuf_tx_DATA;
51unsigned char pktBuf_rx;
52
53unsigned short pktDet_AC_corr, pktDet_AC_energy, pktDet_RSSI_thresh;
54char debug_goodHdrPrint;
55
56//Arrays to track pkt sequence numbers for each partner node
57unsigned char rxSequences[16];
58unsigned char txSequences[16];
59
60unsigned char maximumReSend;
61
62///ID of this node
63unsigned short int myID;
64
65///Full rate modulation selection; QPSK by default
66unsigned int pktFullRate;
67
68//Payload code rate selection
69unsigned int pktCodeRate;
70
71///Buffer for holding a packet-to-xmit across multiple retransmissions
72Macframe txMacframe;
73///Buffer to hold received packet
74Macframe rxMacframe;
75
76///Current 802.11 channel
77unsigned char chan;
78
79//Define handy macros for CSMA MAC packet types
80///Data packet with payload meant for Ethernet transmission
81#define PKTTYPE_DATA 1
82///Acknowledgement packet meant for halting retransmissions
83#define PKTTYPE_ACK 0
84
85///@brief Callback for the depression of the left push button
86///
87///This function is empty by default
88void leftButton() {
89}
90
91///@brief Callback for the depression of the right push button
92///
93///This button switched between different fullrate modulation orders
94void rightButton() {
95    switch(pktFullRate){
96        case HDR_FULLRATE_BPSK:
97            pktFullRate = HDR_FULLRATE_QPSK;
98            xil_printf("QPSK\r\n");
99            break;
100        case HDR_FULLRATE_QPSK:
101            pktFullRate = HDR_FULLRATE_QAM_16;
102            xil_printf("16-QAM\r\n");
103            break;
104        case HDR_FULLRATE_QAM_16:
105            pktFullRate = HDR_FULLRATE_QAM_64;
106            xil_printf("64-QAM\r\n");
107            break;
108        case HDR_FULLRATE_QAM_64:
109            pktFullRate = HDR_FULLRATE_BPSK;
110            xil_printf("BPSK\r\n");
111            break;
112    }
113}
114
115///@brief Callback for the depression of the up push button
116///
117///This button increments the 2.4GHz channel being used; only valid channels (in [1,14]) will be used
118void upButton() {
119    unsigned int newFreq;
120
121    chan = (chan > 13) ? 14 : chan+1;
122    newFreq = warpphy_setChannel(GHZ_2, chan);
123    warpmac_leftHex(chan);
124
125    xil_printf("New Frequency %d\r\n", newFreq);
126}
127
128///@brief Callback for the depression of the middle push button
129///
130///This button decrements the 2.4GHz channel being used; only valid channels (in [1,14]) will be used
131void middleButton(){
132    unsigned int newFreq;
133
134    chan = (chan < 2) ? 1 : chan-1;
135    newFreq = warpphy_setChannel(GHZ_2, chan);
136    warpmac_leftHex(chan);
137
138    xil_printf("New Frequency %d\r\n", newFreq);
139}
140
141
142///@brief Callback for the reception of UART bytes
143///@param uartByte ASCII byte received from UART
144///
145///Provides the user with the bytes that was received over the serial port. This is useful for configuring
146///PHY and MAC parameters in real time on a board.
147void uartRecv_callback(unsigned char uartByte)
148{
149    if(uartByte != 0x0)
150    {
151        xil_printf("(%c)\t", uartByte);
152
153        switch(uartByte)
154        {
155            case ASCII_1:
156                pktFullRate = HDR_FULLRATE_BPSK;
157                xil_printf("Tx Full Rate = BPSK\r\n");
158                break;
159
160            case ASCII_2:
161                pktFullRate = HDR_FULLRATE_QPSK;
162                xil_printf("Tx Full Rate = QPSK\r\n");
163                break;
164
165            case ASCII_4:
166                pktFullRate = HDR_FULLRATE_QAM_16;
167                xil_printf("Tx Full Rate = 16-QAM\r\n");
168                break;
169
170            case ASCII_6:
171                pktFullRate = HDR_FULLRATE_QAM_64;
172                xil_printf("Tx Full Rate = 64-QAM\r\n");
173                break;
174
175            case ASCII_7:
176                pktCodeRate = HDR_CODE_RATE_12;
177                xil_printf("Coding Rate = 1/2\r\n");
178                break;
179            case ASCII_8:
180                pktCodeRate = HDR_CODE_RATE_23;
181                xil_printf("Coding Rate = 2/3\r\n");
182                break;
183            case ASCII_9:
184                pktCodeRate = HDR_CODE_RATE_34;
185                xil_printf("Coding Rate = 3/4\r\n");
186                break;
187            case ASCII_0:
188                pktCodeRate = HDR_CODE_RATE_NONE;
189                xil_printf("Coding Rate = 1 (no coding)\r\n");
190                break;
191            case ASCII_F:
192                if(chan<14) chan++;
193                warpphy_setChannel(GHZ_2, chan);
194                xil_printf("Current channel: %d\r\n",chan);
195                break;
196            case ASCII_f:
197                if(chan>1) chan--;
198                warpphy_setChannel(GHZ_2, chan);
199                xil_printf("Current channel: %d\r\n",chan);
200                break;
201
202            case ASCII_C:
203                pktDet_AC_corr = (pktDet_AC_corr < 250) ? (pktDet_AC_corr+5) : 255;
204                xil_printf("AutoCorr_corr: %d\tAutoCorr_energy: %d\r\n", pktDet_AC_corr, pktDet_AC_energy);
205                warpphy_setAutoCorrDetParams(pktDet_AC_corr, pktDet_AC_energy);
206                break;
207            case ASCII_c:
208                pktDet_AC_corr = (pktDet_AC_corr > 4) ? (pktDet_AC_corr-5) : 0;
209                xil_printf("AutoCorr_corr: %d\tAutoCorr_energy: %d\r\n", pktDet_AC_corr, pktDet_AC_energy);
210                warpphy_setAutoCorrDetParams(pktDet_AC_corr, pktDet_AC_energy);
211                break;
212
213            case ASCII_E:
214                pktDet_AC_energy = (pktDet_AC_energy<2047) ? (pktDet_AC_energy+1) : 2047;
215                xil_printf("AutoCorr_corr: %d\tAutoCorr_energy: %d\r\n", pktDet_AC_corr, pktDet_AC_energy);
216                warpphy_setAutoCorrDetParams(pktDet_AC_corr, pktDet_AC_energy);
217                break;
218            case ASCII_e:
219                pktDet_AC_energy = (pktDet_AC_energy>0) ? (pktDet_AC_energy-1) : 0;
220                xil_printf("AutoCorr_corr: %d\tAutoCorr_energy: %d\r\n", pktDet_AC_corr, pktDet_AC_energy);
221                warpphy_setAutoCorrDetParams(pktDet_AC_corr, pktDet_AC_energy);
222                break;
223               
224            case ASCII_R:
225                pktDet_RSSI_thresh += 100;
226                xil_printf("RSSI_thresh: %d\r\n", pktDet_RSSI_thresh);
227                warpphy_setEnergyDetThresh(pktDet_RSSI_thresh);
228                break;
229
230            case ASCII_r:
231                pktDet_RSSI_thresh -= 100;
232                xil_printf("RSSI_thresh: %d\r\n", pktDet_RSSI_thresh);
233                warpphy_setEnergyDetThresh(pktDet_RSSI_thresh);
234                break;
235            case ASCII_A:
236                xil_printf("Debug good header print ON\r\n");
237                debug_goodHdrPrint = 1;
238                break;
239            case ASCII_a:
240                xil_printf("Debug good header print OFF\r\n");
241                debug_goodHdrPrint = 0;
242                break;
243               
244            default:
245                xil_printf("Undefined command\r\n");
246                break;
247        }
248    }
249
250    return;
251}
252///@brief Callback for the expiration of timers
253///
254///This function is responsible for handling TIMEOUT_TIMER and BACKOFF_TIMER.
255///The job responsibilities of this function are to:
256///-increase the contention window upon the expiration of a TIMEOUT_TIMER
257///-initiate a BACKOFF_TIMER timer upon the expiration of a TIMEOUT_TIMER
258///-retransmit a packet upon the expiration of a BACKOFF_TIMER
259///@param timerType TIMEOUT_TIMER or BACKOFF_TIMER
260void timer_callback(unsigned char timerType) {
261
262    switch(timerType) {
263        case TIMEOUT_TIMER:
264            warpmac_setTimer(BACKOFF_TIMER);
265            break;
266
267        case BACKOFF_TIMER:
268            if(txMacframe.header.remainingTx) {
269                //Copy the header over to the Tx packet buffer
270                warpmac_prepPhyForXmit(&txMacframe, pktBuf_tx_DATA);
271
272                //Send from the Tx packet buffer
273                warpmac_startPhyXmit(pktBuf_tx_DATA);
274                warpmac_leftHex(0xF & (txMacframe.header.remainingTx));
275                //Wait for it to finish
276                warpmac_finishPhyXmit();
277
278                //Start a timeout timer
279                warpmac_setTimer(TIMEOUT_TIMER);
280                warpmac_decrementRemainingReSend(&txMacframe);
281            }
282            else {
283                //Either the packet has been sent the max number of times, or
284                // we just got an ACK and need to backoff before starting with a new packet
285                warpmac_enableDataFromNetwork();
286            }
287            break; //END BACKOFF_TIMER
288    }
289}
290
291
292///@brief Callback for the reception of Ethernet packets
293///
294///This function is called by the ethernet MAC drivers
295///when a packet is available to send. This function fills
296///the Macframe transmit buffer with the packet and sends
297///it over the OFDM link
298///@param length Length, in bytes, of received payload (Ethernet or dummy payload length)
299///@param payload Pointer to first byte of received payload (first byte of Ethernet or dummy payload)
300void dataFromNetworkLayer_callback(Xuint32 length, char* payload){
301    unsigned char destNode;
302
303    //Reset the contention window to its minimum
304    warpmac_resetCurrentCW();
305
306    //Disable further Ethernet packets (will be re-enabled after this packet is ACK'd or dropped)
307    warpmac_disableDataFromNetwork();
308
309    //Update the Tx packet header with this packet's values
310    txMacframe.header.length = length;
311    txMacframe.header.pktType = PKTTYPE_DATA;
312
313    //Set the modulation scheme for the packet's full-rate symbols
314    txMacframe.header.fullRate = pktFullRate;
315
316    //Set the code rate for the packet's payload
317    txMacframe.header.codeRate = pktCodeRate;
318
319    //For now, assume our destination is our opposite ID (all traffic is 0 <-> 1)
320    destNode = (myID+1)%2;
321
322    //Copy in the packet's destination MAC address
323    txMacframe.header.destAddr = (unsigned short int)(NODEID_TO_ADDR(destNode));
324
325    //Use the next sequence number for this node (top four bits) and resend count of 0 (bottom four bits)
326    txSequences[destNode] = (txSequences[destNode] + 1) % 256;
327    txMacframe.header.seqNum = txSequences[destNode];
328
329    //Set the remaining Tx counter to the maximum numeber of transmissions
330    txMacframe.header.remainingTx = (maximumReSend+1);
331
332    if(warpmac_carrierSense()) {
333        //If the modium is idle:
334
335        //Copy the header to the Tx packet buffer
336        warpmac_prepPhyForXmit(&txMacframe, pktBuf_tx_DATA);
337
338        //Transmit the packet
339        warpmac_startPhyXmit(pktBuf_tx_DATA);
340        warpmac_leftHex(0xF & (txMacframe.header.remainingTx));
341       
342        //Wait for it to finish
343        warpmac_finishPhyXmit();
344
345        //Start a timeout timer
346        warpmac_setTimer(TIMEOUT_TIMER);
347        warpmac_decrementRemainingReSend(&txMacframe);
348    }
349    else {
350        //Medium was busy; start a backoff timer
351        warpmac_setTimer(BACKOFF_TIMER);
352    }
353
354    return;
355}
356
357///@brief Callback for the reception of bad wireless headers
358void phyRx_badHeader_callback() {
359
360    //Don't do anything with the packet (it had errors, and can't be trusted)
361   
362    //Increment the bottom LEDs
363    warpmac_incrementLEDLow();
364
365    return;
366}
367
368///@brief Callback for the reception of good wireless headers
369///
370///This function then polls the PHY to determine if the entire packet passes checksum
371///thereby triggering the transmission of the ACK and the transmission of the received
372///data over Ethernet.
373///@param packet Pointer to received Macframe
374int phyRx_goodHeader_callback(Macframe* packet){
375
376    unsigned char state = PHYRXSTATUS_INCOMPLETE;
377    unsigned char srcNode;
378    unsigned char shouldSend = 0;
379
380    if(debug_goodHdrPrint) {
381        xil_printf("GH: RSSI=%4d\tAGC=%d/%2d\r\n",
382            ofdm_txrx_mimo_ReadReg_Rx_PktDet_midPktRSSI_antA(),
383            OFDM_AGC_MIMO_ReadReg_GRF_A(0),
384            OFDM_AGC_MIMO_ReadReg_GBB_A(0));
385    }
386       
387    //Calculate the node ID from the packet's source MAC address
388    srcNode = ADDR_TO_NODEID( (packet->header.srcAddr) );
389
390    //If the packet is addressed to this node
391    if( packet->header.destAddr == (NODEID_TO_ADDR(myID)) ) {
392
393        switch(packet->header.pktType) {
394            //If received packet is data
395            case PKTTYPE_DATA:
396                //At this point, we have pre-loaded the PHY transmitter with the ACK in hoping that
397                //the packet passes checksum. Now we wait for the state of the received to packet
398                //to move from PHYRXSTATUS_INCOMPLETE to either PHYRXSTATUS_GOOD or PHYRXSTATUS_BAD
399
400                //Poll the PHY until the payload is declared good or bad
401                state = warpmac_finishPhyRecv();
402
403                if(state & PHYRXSTATUS_GOOD){
404                    //The auto-reponder will send the pre-programmed ACK automatically
405                    //User code only needs to update its stats, then check to see the PHY is finished transmitting
406
407                    //Toggle the top LEDs
408                    warpmac_incrementLEDHigh();
409
410                    //Update the right-hex display with the current sequence number
411                    //warpmac_leftHex(0xF & (packet->header.seqNum));
412
413                    //Check if the last received seq number for this partner node matches this received pkt
414                    // If not, record the new number and allow the pkt to be forwarded over the wire
415                    if(rxSequences[srcNode] != (packet->header.seqNum))
416                    {
417                        //Not a duplicate packet; update this partner's last-known sequence number
418                        rxSequences[srcNode] = (packet->header.seqNum);
419                        shouldSend = 1;
420                    }
421
422                    //Starts the DMA transfer of the payload into the EMAC
423                    if(shouldSend) warpmac_prepPktToNetwork((void *)warpphy_getBuffAddr(pktBuf_rx)+NUM_HEADER_BYTES, (packet->header.length));
424
425                    //Blocks until the PHY is finished sending and enables the receiver
426                    warpmac_finishPhyXmit();
427
428                    //Waits until the DMA transfer is complete, then starts the EMAC
429                    if(shouldSend) warpmac_startPktToNetwork((packet->header.length));
430                }
431
432                if(state & PHYRXSTATUS_BAD) {
433                    warpmac_incrementLEDLow();
434                }
435
436                break; //END PKTTYPE_DATA
437
438            case PKTTYPE_ACK:
439                //Clear the TIMEOUT and enable Ethernet
440                if(warpmac_inTimeout()) {
441                    warpmac_incrementLEDHigh();
442
443                    //Clear the timeout timer, set when we transmitted the data packet
444                    warpmac_clearTimer(TIMEOUT_TIMER);
445
446                    //Clear the remaining transmit count to assure this packet won't be re-transmitted
447                    txMacframe.header.remainingTx = 0;
448
449                    //Start a backoff, to gaurantee a random time before attempting to transmit again
450                    warpmac_setTimer(BACKOFF_TIMER);
451
452                    //Re-enable EMAC polling immediately (for testing; using the post-ACK backoff is better for real use)
453                    //warpmac_enableDataFromNetwork();
454                }
455                else {
456                    //Got an unexpected ACK; ignore it
457                }
458
459                break; //END PKTTYPE_ACK
460        }
461    }
462    else {
463        state = warpmac_finishPhyRecv();
464    }
465    //Return 0, indicating we didn't clear the PHY status bits (WARPMAC will handle it)
466    return 0;
467}
468
469///@brief Main function
470///
471///This function configures MAC parameters, enables the underlying frameworks, and then loops forever.
472int main(){
473    print("\fReference Design v18 CSMAMAC\r\n");
474
475    //Initialize global variables
476    chan = 11;
477
478    //Assign the packet buffers in the PHY
479    // The auto responder can't transmit from buffer 0, so we use it for Rx packets
480    // The other assignments (DATA/ACK) are arbitrary; any buffer in [1,30] will work
481    pktBuf_rx = 1;
482    pktBuf_tx_DATA = 2;
483    pktBuf_tx_ACK = 3;
484
485    //Set the full-rate modulation to QPSK by default
486//  pktFullRate = HDR_FULLRATE_QAM_16;
487    pktFullRate = HDR_FULLRATE_QPSK;
488
489    //Set the payload coding rate to 3/4 rate by default
490    pktCodeRate = HDR_CODE_RATE_34;
491
492    //Initialize the MAC/PHY frameworks
493    warpmac_init();
494    maximumReSend = 8;
495    warpmac_setMaxResend(maximumReSend);
496    warpmac_setMaxCW(5);
497    warpmac_setTimeout(120);
498    warpmac_setSlotTime(22);
499
500    //Read Dip Switch value from FPGA board.
501    //This value will be used as an index into the routing table for other nodes
502    myID = (unsigned short int)warpmac_getMyId();
503    warpmac_rightHex(myID);
504
505    //Configure the PHY and radios for single antenna (SISO) mode
506    warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA);
507    //warpphy_setAntennaMode(TX_ANTMODE_MULTPLX, RX_ANTMODE_MULTPLX);
508    //warpphy_setAntennaMode(TX_ANTMODE_ALAMOUTI_ANTA, RX_ANTMODE_ALAMOUTI_ANTA);
509
510#ifdef WARP_HW_VER_v3
511    //Set the OFDM Rx detection thresholds
512    warpphy_setCarrierSenseThresh(4000); //Carrier sense thresh (in [0,16368])
513    warpphy_setEnergyDetThresh(6500);       //Min RSSI (in [0,16368])
514    warpphy_setAutoCorrDetParams(50, 20);   //Min auto-correlation (UFix8_7) and min energy (UFix16_8)
515    warpphy_setLongCorrThresh(10000);       //Min cross-correlation (in [0,45e3])
516
517    //Set the default Tx gain (in [0,63])
518    warpphy_setTxPower(50);
519#else
520    //Set the OFDM Rx detection thresholds (copied from OFDM ref des v17 for now)
521    warpphy_setCarrierSenseThresh(12000); //Carrier sense thresh (in [0,16368])
522    warpphy_setEnergyDetThresh(7000);       //Min RSSI (in [0,16368])
523    warpphy_setAutoCorrDetParams(90, 20);   //Min auto-correlation (UFix8_7) and min energy (UFix16_8)
524    warpphy_setLongCorrThresh(8000);        //Min cross-correlation (in [0,45e3])
525
526    //Set the default Tx gain (in [0,63])
527    warpphy_setTxPower(55);
528#endif
529
530    //Set the default center frequency
531    warpphy_setChannel(GHZ_2, 11);
532   
533
534    //Rx buffer is where the EMAC will DMA Wireless payloads from
535    warpmac_setRxBuffers(&rxMacframe, pktBuf_rx);
536
537    //Tx buffer is where the EMAC will DMA Ethernet payloads to
538    warpmac_setPHYTxBuffer(pktBuf_tx_DATA);
539    warpmac_setEMACRxBuffer(pktBuf_tx_DATA);
540
541    //Set the modulation scheme use for base rate (header) symbols
542    warpmac_setBaseRate(QPSK);
543
544    //Copy this node's MAC address into the Tx buffer's source address field
545    txMacframe.header.srcAddr = (unsigned short int)(NODEID_TO_ADDR(myID));
546
547    //Register callbacks
548    warpmac_setCallback(EVENT_UPBUTTON, (void *)upButton);
549    warpmac_setCallback(EVENT_LEFTBUTTON, (void *)leftButton);
550    warpmac_setCallback(EVENT_RIGHTBUTTON, (void *)rightButton);
551    warpmac_setCallback(EVENT_MIDDLEBUTTON, (void *)middleButton);
552    warpmac_setCallback(EVENT_TIMER, (void *)timer_callback);
553    warpmac_setCallback(EVENT_DATAFROMNETWORK, (void *)dataFromNetworkLayer_callback);
554    warpmac_setCallback(EVENT_PHYGOODHEADER, (void *)phyRx_goodHeader_callback);
555    warpmac_setCallback(EVENT_PHYBADHEADER, (void *)phyRx_badHeader_callback);
556    warpmac_setCallback(EVENT_UARTRX, (void *)uartRecv_callback);
557
558    //Set the default center frequency
559    warpphy_setChannel(GHZ_2, chan);
560
561    //Enable carrier sensing
562    warpmac_setCSMA(1);
563
564    /******** START autoResponse setup *******/
565    //Setup the PHY's autoResponse system
566    // For CSMA, it is configured to send pktBuf pktBuf_tx_ACK when a good DATA packet is received addressed to this node
567
568    //Match condition 0: received header's destination address is this node's address
569    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_DSTADDR, 2, htons(NODEID_TO_ADDR(myID)));
570    mimo_ofdmTxRx_setMatch0(autoResp_matchCond);
571
572    //Match condition 1: received header's type is DATA
573    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_TYPE, 1, PKTTYPE_DATA);
574    mimo_ofdmTxRx_setMatch1(autoResp_matchCond);
575
576    //Configure the header translator to use the Rx pkt's src address as the outgoing pkt's dst address
577    // Addresses are two bytes, so two entries in the header translator need to be overridden
578    // Except for these bytes, the ACK pktBuf's contents will be sent unaltered
579    // PHY_HEADERTRANSLATE_SET(templatePktBuf, byteAddrToOverwrite, srcPktBuf, srcByteAddr)
580    PHY_HEADERTRANSLATE_SET(pktBuf_tx_ACK, (PKTHEADER_INDX_DSTADDR+0), pktBuf_rx, (PKTHEADER_INDX_SRCADDR+0));
581    PHY_HEADERTRANSLATE_SET(pktBuf_tx_ACK, (PKTHEADER_INDX_DSTADDR+1), pktBuf_rx, (PKTHEADER_INDX_SRCADDR+1));
582
583    //Create a template ACK packet
584    templatePkt.header.fullRate = pktFullRate;
585    templatePkt.header.codeRate = pktCodeRate;
586    templatePkt.header.length = 0;
587    templatePkt.header.srcAddr = (unsigned short)(NODEID_TO_ADDR(myID));
588    templatePkt.header.pktType = PKTTYPE_ACK;
589
590    //Copy the header down to the PHY's packet buffer
591    // This doesn't actually send anything; the autoResponse system will use this template when sending ACKs
592    warpmac_prepPhyForXmit(&templatePkt, pktBuf_tx_ACK);
593
594    //Action defitions come last; bad things might happen if an action is enabled (set non-zero) before the template pkt is ready.
595    //All actors are disabled during warpphy_init; only load non-zero configurations for actors you intend to use
596
597    //Action 0: send pkt from buf pktBuf_tx_ACK when match0 & match1 & goodPkt, using header translation
598    autoResp_action = PHY_AUTORESPONSE_TXACTION_CONFIG(pktBuf_tx_ACK, PHY_AUTORESPONSE_ACT_TRANS_HDR, 0, (PHY_AUTORESPONSE_REQ_MATCH0 | PHY_AUTORESPONSE_REQ_MATCH1 | PHY_AUTORESPONSE_REQ_GOODHDR | PHY_AUTORESPONSE_REQ_GOODPKT));
599    mimo_ofdmTxRx_setAction0(autoResp_action);
600    /******* END autoResponse setup ******/
601
602    //Listen for new packets to send (either from Ethernet or local dummy packets)
603    warpmac_enableDataFromNetwork();
604
605    xil_printf("Beginning main loop\r\n");
606
607   
608    /******* DEBUG STUFF *******/
609    debug_goodHdrPrint = 0;
610   
611    while(1)
612    {
613        //Poll the timer, PHY and user I/O forever; actual processing will happen via callbacks above
614        warpmac_pollPeripherals();
615    }
616
617    return 0;
618}
Note: See TracBrowser for help on using the repository browser.