source: ResearchApps/MAC/CSMAMAC/csmaMac.c

Last change on this file was 1890, checked in by murphpo, 11 years ago
  • Property svn:eol-style set to native
File size: 20.2 KB
RevLine 
[676]1/*! \file csmaMac.c
[941]2 \brief Carrier-Sensing Random Access MAC.
[1453]3
[1816]4 @version 18.0
[1215]5 @author Chris Hunter and Patrick Murphy
[1169]6
[941]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.
[1453]15
[941]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.
[1453]21
[941]22 In its current state, the project acts as
[1712]23 a true Ethernet MAC-level wireless bridge.
24 Any Ethernet activity that appears on one
[941]25 WARP will be sent to another via the custom
26 wireless link.
[1453]27
[1215]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
[1712]31 relative to the start time of the preceding DATA.
[1215]32
[941]33 */
[594]34#include "warpmac.h"
[676]35#include "warpphy.h"
[824]36#include "csmaMac.h"
[1712]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"
[594]42#include "xparameters.h"
[1890]43#include "warp_hw_ver.h"
[594]44
[1223]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
[1639]53unsigned short pktDet_AC_corr, pktDet_AC_energy, pktDet_RSSI_thresh;
54char debug_goodHdrPrint;
55
[1110]56//Arrays to track pkt sequence numbers for each partner node
57unsigned char rxSequences[16];
58unsigned char txSequences[16];
59
[1174]60unsigned char maximumReSend;
61
[1579]62///ID of this node
[1215]63unsigned short int myID;
[594]64
[1063]65///Full rate modulation selection; QPSK by default
66unsigned int pktFullRate;
67
[1617]68//Payload code rate selection
[1110]69unsigned int pktCodeRate;
70
[679]71///Buffer for holding a packet-to-xmit across multiple retransmissions
[1380]72Macframe txMacframe;
[679]73///Buffer to hold received packet
[1380]74Macframe rxMacframe;
[594]75
[987]76///Current 802.11 channel
[1063]77unsigned char chan;
[941]78
[1169]79//Define handy macros for CSMA MAC packet types
[679]80///Data packet with payload meant for Ethernet transmission
[1579]81#define PKTTYPE_DATA 1
[990]82///Acknowledgement packet meant for halting retransmissions
[1579]83#define PKTTYPE_ACK 0
[594]84
[906]85///@brief Callback for the depression of the left push button
86///
[1169]87///This function is empty by default
[1380]88void leftButton() {
[906]89}
90
91///@brief Callback for the depression of the right push button
92///
[1169]93///This button switched between different fullrate modulation orders
[1380]94void rightButton() {
[1169]95    switch(pktFullRate){
96        case HDR_FULLRATE_BPSK:
97            pktFullRate = HDR_FULLRATE_QPSK;
[1171]98            xil_printf("QPSK\r\n");
[1169]99            break;
100        case HDR_FULLRATE_QPSK:
101            pktFullRate = HDR_FULLRATE_QAM_16;
[1171]102            xil_printf("16-QAM\r\n");
[1169]103            break;
104        case HDR_FULLRATE_QAM_16:
105            pktFullRate = HDR_FULLRATE_QAM_64;
[1171]106            xil_printf("64-QAM\r\n");
[1169]107            break;
108        case HDR_FULLRATE_QAM_64:
109            pktFullRate = HDR_FULLRATE_BPSK;
[1171]110            xil_printf("BPSK\r\n");
[1169]111            break;
112    }
[906]113}
114
115///@brief Callback for the depression of the up push button
116///
[1063]117///This button increments the 2.4GHz channel being used; only valid channels (in [1,14]) will be used
[1380]118void upButton() {
[1063]119    unsigned int newFreq;
[1453]120
[1169]121    chan = (chan > 13) ? 14 : chan+1;
[1063]122    newFreq = warpphy_setChannel(GHZ_2, chan);
[906]123    warpmac_leftHex(chan);
[1453]124
[1169]125    xil_printf("New Frequency %d\r\n", newFreq);
[906]126}
127
128///@brief Callback for the depression of the middle push button
129///
[1063]130///This button decrements the 2.4GHz channel being used; only valid channels (in [1,14]) will be used
[1380]131void middleButton(){
[1063]132    unsigned int newFreq;
[1453]133
[1169]134    chan = (chan < 2) ? 1 : chan-1;
135    newFreq = warpphy_setChannel(GHZ_2, chan);
[906]136    warpmac_leftHex(chan);
[1453]137
[1169]138    xil_printf("New Frequency %d\r\n", newFreq);
[906]139}
140
[1169]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.
[1063]147void uartRecv_callback(unsigned char uartByte)
148{
149    if(uartByte != 0x0)
150    {
151        xil_printf("(%c)\t", uartByte);
[1453]152
[1063]153        switch(uartByte)
154        {
155            case ASCII_1:
[1110]156                pktFullRate = HDR_FULLRATE_BPSK;
[1063]157                xil_printf("Tx Full Rate = BPSK\r\n");
[1169]158                break;
[1453]159
[1063]160            case ASCII_2:
[1110]161                pktFullRate = HDR_FULLRATE_QPSK;
[1063]162                xil_printf("Tx Full Rate = QPSK\r\n");
[1169]163                break;
[1453]164
[1063]165            case ASCII_4:
[1110]166                pktFullRate = HDR_FULLRATE_QAM_16;
[1063]167                xil_printf("Tx Full Rate = 16-QAM\r\n");
[1169]168                break;
[1453]169
[1063]170            case ASCII_6:
[1110]171                pktFullRate = HDR_FULLRATE_QAM_64;
[1063]172                xil_printf("Tx Full Rate = 64-QAM\r\n");
[1164]173                break;
[1617]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;
[1171]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;
[1639]201
[1171]202            case ASCII_C:
[1639]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);
[1171]206                break;
207            case ASCII_c:
[1639]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);
[1171]211                break;
[1639]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);
[1171]217                break;
[1639]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);
[1171]222                break;
[1639]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);
[1396]228                break;
229
[1639]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);
[1396]234                break;
[1639]235            case ASCII_A:
[1712]236                xil_printf("Debug good header print ON\r\n");
[1639]237                debug_goodHdrPrint = 1;
[1396]238                break;
[1639]239            case ASCII_a:
[1712]240                xil_printf("Debug good header print OFF\r\n");
[1639]241                debug_goodHdrPrint = 0;
[1396]242                break;
[1639]243               
[1063]244            default:
245                xil_printf("Undefined command\r\n");
[1169]246                break;
[1063]247        }
248    }
[1453]249
[1063]250    return;
251}
[679]252///@brief Callback for the expiration of timers
253///
[1648]254///This function is responsible for handling TIMEOUT_TIMER and BACKOFF_TIMER.
[679]255///The job responsibilities of this function are to:
[1648]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
[1579]260void timer_callback(unsigned char timerType) {
261
262    switch(timerType) {
[1178]263        case TIMEOUT_TIMER:
264            warpmac_setTimer(BACKOFF_TIMER);
[1169]265            break;
[1579]266
[1178]267        case BACKOFF_TIMER:
[1634]268            if(txMacframe.header.remainingTx) {
[1579]269                //Copy the header over to the Tx packet buffer
[1380]270                warpmac_prepPhyForXmit(&txMacframe, pktBuf_tx_DATA);
271
[1579]272                //Send from the Tx packet buffer
[1223]273                warpmac_startPhyXmit(pktBuf_tx_DATA);
[1816]274                warpmac_leftHex(0xF & (txMacframe.header.remainingTx));
[1380]275                //Wait for it to finish
[1174]276                warpmac_finishPhyXmit();
[1380]277
[1174]278                //Start a timeout timer
[1178]279                warpmac_setTimer(TIMEOUT_TIMER);
[1380]280                warpmac_decrementRemainingReSend(&txMacframe);
[1174]281            }
[1579]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
[594]288    }
289}
290
[795]291
[679]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
[1647]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)
[1215]300void dataFromNetworkLayer_callback(Xuint32 length, char* payload){
[1110]301    unsigned char destNode;
[1453]302
[1579]303    //Reset the contention window to its minimum
304    warpmac_resetCurrentCW();
[1453]305
[1579]306    //Disable further Ethernet packets (will be re-enabled after this packet is ACK'd or dropped)
[1215]307    warpmac_disableDataFromNetwork();
[1579]308
309    //Update the Tx packet header with this packet's values
[1380]310    txMacframe.header.length = length;
[1579]311    txMacframe.header.pktType = PKTTYPE_DATA;
[1453]312
[736]313    //Set the modulation scheme for the packet's full-rate symbols
[1380]314    txMacframe.header.fullRate = pktFullRate;
[1453]315
[1110]316    //Set the code rate for the packet's payload
[1380]317    txMacframe.header.codeRate = pktCodeRate;
[1453]318
[1110]319    //For now, assume our destination is our opposite ID (all traffic is 0 <-> 1)
320    destNode = (myID+1)%2;
[1453]321
[1579]322    //Copy in the packet's destination MAC address
323    txMacframe.header.destAddr = (unsigned short int)(NODEID_TO_ADDR(destNode));
324
[1110]325    //Use the next sequence number for this node (top four bits) and resend count of 0 (bottom four bits)
[1325]326    txSequences[destNode] = (txSequences[destNode] + 1) % 256;
[1380]327    txMacframe.header.seqNum = txSequences[destNode];
[1453]328
[1579]329    //Set the remaining Tx counter to the maximum numeber of transmissions
[1634]330    txMacframe.header.remainingTx = (maximumReSend+1);
[1453]331
[1579]332    if(warpmac_carrierSense()) {
[1281]333        //If the modium is idle:
334
[1579]335        //Copy the header to the Tx packet buffer
[1380]336        warpmac_prepPhyForXmit(&txMacframe, pktBuf_tx_DATA);
[1281]337
338        //Transmit the packet
[1223]339        warpmac_startPhyXmit(pktBuf_tx_DATA);
[1816]340        warpmac_leftHex(0xF & (txMacframe.header.remainingTx));
[1490]341       
[1281]342        //Wait for it to finish
[941]343        warpmac_finishPhyXmit();
[1281]344
[941]345        //Start a timeout timer
[1178]346        warpmac_setTimer(TIMEOUT_TIMER);
[1380]347        warpmac_decrementRemainingReSend(&txMacframe);
[594]348    }
[1579]349    else {
[1281]350        //Medium was busy; start a backoff timer
[1178]351        warpmac_setTimer(BACKOFF_TIMER);
[594]352    }
[1453]353
[1082]354    return;
[594]355}
356
[941]357///@brief Callback for the reception of bad wireless headers
[954]358void phyRx_badHeader_callback() {
[1579]359
360    //Don't do anything with the packet (it had errors, and can't be trusted)
361   
362    //Increment the bottom LEDs
[594]363    warpmac_incrementLEDLow();
[1453]364
[1063]365    return;
[594]366}
367
[855]368///@brief Callback for the reception of good wireless headers
[679]369///
[946]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.
[679]373///@param packet Pointer to received Macframe
[1579]374int phyRx_goodHeader_callback(Macframe* packet){
[1453]375
[1281]376    unsigned char state = PHYRXSTATUS_INCOMPLETE;
[1110]377    unsigned char srcNode;
378    unsigned char shouldSend = 0;
[1453]379
[1639]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       
[1325]387    //Calculate the node ID from the packet's source MAC address
[1281]388    srcNode = ADDR_TO_NODEID( (packet->header.srcAddr) );
[1453]389
[984]390    //If the packet is addressed to this node
[1579]391    if( packet->header.destAddr == (NODEID_TO_ADDR(myID)) ) {
[1453]392
[1579]393        switch(packet->header.pktType) {
[1281]394            //If received packet is data
[1579]395            case PKTTYPE_DATA:
[984]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
[1281]398                //to move from PHYRXSTATUS_INCOMPLETE to either PHYRXSTATUS_GOOD or PHYRXSTATUS_BAD
[1215]399
[1579]400                //Poll the PHY until the payload is declared good or bad
[1215]401                state = warpmac_finishPhyRecv();
[1453]402
[1281]403                if(state & PHYRXSTATUS_GOOD){
[1235]404                    //The auto-reponder will send the pre-programmed ACK automatically
[1579]405                    //User code only needs to update its stats, then check to see the PHY is finished transmitting
[1235]406
407                    //Toggle the top LEDs
[1220]408                    warpmac_incrementLEDHigh();
[1453]409
[1281]410                    //Update the right-hex display with the current sequence number
[1816]411                    //warpmac_leftHex(0xF & (packet->header.seqNum));
[1453]412
[1110]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
[1579]415                    if(rxSequences[srcNode] != (packet->header.seqNum))
[1281]416                    {
417                        //Not a duplicate packet; update this partner's last-known sequence number
[1235]418                        rxSequences[srcNode] = (packet->header.seqNum);
419                        shouldSend = 1;
[1453]420                    }
421
[941]422                    //Starts the DMA transfer of the payload into the EMAC
[1380]423                    if(shouldSend) warpmac_prepPktToNetwork((void *)warpphy_getBuffAddr(pktBuf_rx)+NUM_HEADER_BYTES, (packet->header.length));
[1453]424
[941]425                    //Blocks until the PHY is finished sending and enables the receiver
426                    warpmac_finishPhyXmit();
[1453]427
[941]428                    //Waits until the DMA transfer is complete, then starts the EMAC
[1380]429                    if(shouldSend) warpmac_startPktToNetwork((packet->header.length));
[941]430                }
[1453]431
[1579]432                if(state & PHYRXSTATUS_BAD) {
[941]433                    warpmac_incrementLEDLow();
434                }
[1453]435
[1579]436                break; //END PKTTYPE_DATA
[1453]437
[1579]438            case PKTTYPE_ACK:
[984]439                //Clear the TIMEOUT and enable Ethernet
[1579]440                if(warpmac_inTimeout()) {
[1220]441                    warpmac_incrementLEDHigh();
[1223]442
[1281]443                    //Clear the timeout timer, set when we transmitted the data packet
[1178]444                    warpmac_clearTimer(TIMEOUT_TIMER);
[1281]445
446                    //Clear the remaining transmit count to assure this packet won't be re-transmitted
[1634]447                    txMacframe.header.remainingTx = 0;
[1453]448
[1281]449                    //Start a backoff, to gaurantee a random time before attempting to transmit again
[1399]450                    warpmac_setTimer(BACKOFF_TIMER);
[1396]451
452                    //Re-enable EMAC polling immediately (for testing; using the post-ACK backoff is better for real use)
[1579]453                    //warpmac_enableDataFromNetwork();
[594]454                }
[1579]455                else {
456                    //Got an unexpected ACK; ignore it
457                }
[1453]458
[1579]459                break; //END PKTTYPE_ACK
[594]460        }
461    }
[1636]462    else {
463        state = warpmac_finishPhyRecv();
464    }
[1579]465    //Return 0, indicating we didn't clear the PHY status bits (WARPMAC will handle it)
466    return 0;
[594]467}
468
[679]469///@brief Main function
470///
471///This function configures MAC parameters, enables the underlying frameworks, and then loops forever.
[1453]472int main(){
[1890]473    print("\fReference Design v18 CSMAMAC\r\n");
[1453]474
[1063]475    //Initialize global variables
[1816]476    chan = 11;
[1453]477
[1235]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
[1579]481    pktBuf_rx = 1;
482    pktBuf_tx_DATA = 2;
483    pktBuf_tx_ACK = 3;
[1235]484
[1063]485    //Set the full-rate modulation to QPSK by default
[1816]486//  pktFullRate = HDR_FULLRATE_QAM_16;
487    pktFullRate = HDR_FULLRATE_QPSK;
[1453]488
[1617]489    //Set the payload coding rate to 3/4 rate by default
490    pktCodeRate = HDR_CODE_RATE_34;
[1453]491
[1281]492    //Initialize the MAC/PHY frameworks
[941]493    warpmac_init();
[1174]494    maximumReSend = 8;
495    warpmac_setMaxResend(maximumReSend);
[941]496    warpmac_setMaxCW(5);
[1617]497    warpmac_setTimeout(120);
[1281]498    warpmac_setSlotTime(22);
[1215]499
[1281]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();
[1380]503    warpmac_rightHex(myID);
[1453]504
[1235]505    //Configure the PHY and radios for single antenna (SISO) mode
[1579]506    warpphy_setAntennaMode(TX_ANTMODE_SISO_ANTA, RX_ANTMODE_SISO_ANTA);
[1634]507    //warpphy_setAntennaMode(TX_ANTMODE_MULTPLX, RX_ANTMODE_MULTPLX);
[1579]508    //warpphy_setAntennaMode(TX_ANTMODE_ALAMOUTI_ANTA, RX_ANTMODE_ALAMOUTI_ANTA);
[1453]509
[1816]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)
[1636]524    warpphy_setLongCorrThresh(8000);        //Min cross-correlation (in [0,45e3])
[1816]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);
[1617]532   
[1816]533
[986]534    //Rx buffer is where the EMAC will DMA Wireless payloads from
[1380]535    warpmac_setRxBuffers(&rxMacframe, pktBuf_rx);
536
[986]537    //Tx buffer is where the EMAC will DMA Ethernet payloads to
[1380]538    warpmac_setPHYTxBuffer(pktBuf_tx_DATA);
[1579]539    warpmac_setEMACRxBuffer(pktBuf_tx_DATA);
[1453]540
[1281]541    //Set the modulation scheme use for base rate (header) symbols
542    warpmac_setBaseRate(QPSK);
543
[814]544    //Copy this node's MAC address into the Tx buffer's source address field
[1380]545    txMacframe.header.srcAddr = (unsigned short int)(NODEID_TO_ADDR(myID));
[1453]546
[986]547    //Register callbacks
[1380]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);
[1215]557
[814]558    //Set the default center frequency
[941]559    warpphy_setChannel(GHZ_2, chan);
[1453]560
[986]561    //Enable carrier sensing
[1380]562    warpmac_setCSMA(1);
[1453]563
[1223]564    /******** START autoResponse setup *******/
565    //Setup the PHY's autoResponse system
[1281]566    // For CSMA, it is configured to send pktBuf pktBuf_tx_ACK when a good DATA packet is received addressed to this node
[1453]567
[1281]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)));
[1223]570    mimo_ofdmTxRx_setMatch0(autoResp_matchCond);
571
[1453]572    //Match condition 1: received header's type is DATA
[1579]573    autoResp_matchCond = PHY_AUTORESPONSE_MATCH_CONFIG(PKTHEADER_INDX_TYPE, 1, PKTTYPE_DATA);
[1223]574    mimo_ofdmTxRx_setMatch1(autoResp_matchCond);
[1453]575
[1223]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));
[1220]582
[1223]583    //Create a template ACK packet
584    templatePkt.header.fullRate = pktFullRate;
585    templatePkt.header.codeRate = pktCodeRate;
586    templatePkt.header.length = 0;
[1281]587    templatePkt.header.srcAddr = (unsigned short)(NODEID_TO_ADDR(myID));
[1579]588    templatePkt.header.pktType = PKTTYPE_ACK;
[1453]589
[1223]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
[1281]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
[1223]596
[1235]597    //Action 0: send pkt from buf pktBuf_tx_ACK when match0 & match1 & goodPkt, using header translation
[1281]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));
[1223]599    mimo_ofdmTxRx_setAction0(autoResp_action);
600    /******* END autoResponse setup ******/
[1453]601
[1223]602    //Listen for new packets to send (either from Ethernet or local dummy packets)
603    warpmac_enableDataFromNetwork();
[1453]604
[1171]605    xil_printf("Beginning main loop\r\n");
[1453]606
[1639]607   
608    /******* DEBUG STUFF *******/
609    debug_goodHdrPrint = 0;
610   
[1281]611    while(1)
612    {
613        //Poll the timer, PHY and user I/O forever; actual processing will happen via callbacks above
[1164]614        warpmac_pollPeripherals();
[731]615    }
[1453]616
[1712]617    return 0;
[594]618}
Note: See TracBrowser for help on using the repository browser.