root/PlatformSupport/WARPMAC/warpmac_alamouti.c

Revision 723, 46.5 kB (checked in by murphpo, 10 months ago)

removing extra properties

Line 
1//WARPMAC Framework
2//v2.3 (SVN rev X)
3/***************CHANGELOG*****************
4+updated to use radios in slots 2 and 3
5******************************************/
6/*****************WARPMAC*****************
7Description: This framework allows for custom
8MAC implementations on WARP. For a description
9of the functions, see:
10http://warp.rice.edu/trac/wiki/WARPMAC
11******************************************/
12#include "xparameters.h"
13#include "xemac.h"
14#include <xstatus.h>
15#include "xintc.h"
16#include "xgpio.h"
17#include <errno.h>
18#include "xexception_l.h"
19
20//Header files for WARP peripheral drivers
21#include "ofdm_txrx_alamouti.h"
22#include "ofdm_AGC_mimo.h"
23#include "ofdm_timer.h"
24#include "ofdm_pktDetector_mimo.h"
25#include "EEPROM.h"
26#include "radio_controller_basic.h"
27#include "radio_controller_ext.h"
28#include "radio_controller_adv.h"
29
30//Header files for WARP libraries
31#include "warpmac.h"
32
33//This define enables per-packet printfs for debugging
34// This *kills* performance & timing - use with caution
35//#define DEBUG_PKT_PRINT
36
37Maccontrol controlStruct;
38XGpio Gpio;
39
40////Globals for PHY Debugging////
41int agctarget = -13;
42int agcnoiseEst = -95;
43
44unsigned int numTrainingSyms = 2;
45unsigned int pktDly = 58;//251;
46unsigned char globalReset = 0;
47
48//numBaseRate must be zero in the current version of the Alamouti OFDM core
49unsigned int numBaseRate = 0;
50
51unsigned char mod_fullRate = 2;
52
53//Define a bunch of cryptic constants for the PHY's phase tracking filter
54#define INIT_A_KPVAL 0//0x7FFFFFFF//0xA6800
55#define INIT_B_KIVAL 0x2500//xD000//x380000//0x7FFFFFFF//0xA6800
56#define INIT_B_KPVAL 0xD0000//x2F000//x2620000//x7FFFFFFF//0x54afb0//0x1BC7D10//0x2C3C38//0xA6800
57#define INIT_PN_KVAL 0x2700000//xFFFFFFFF
58#define INIT_PN_KAlphaVAL 0x40000000
59#define INIT_PN_KBetaVAL 0x40000000
60#define INIT_PN_KGammaVAL 0x40000000
61#define INIT_RXFFTOFSET 10
62unsigned int A_KPval = INIT_A_KPVAL;
63unsigned int B_KIval = INIT_B_KIVAL;
64unsigned int B_KPval = INIT_B_KPVAL;
65unsigned int PN_KVal = INIT_PN_KVAL;
66unsigned int PN_KAlphaVal = INIT_PN_KAlphaVAL;
67unsigned int PN_KBetaVal = INIT_PN_KBetaVAL;
68unsigned int PN_KGammaVal = INIT_PN_KGammaVAL;
69unsigned int RxFFT_Window_Offset = INIT_RXFFTOFSET;
70/////////////////////////////////
71
72///Global LED states////
73unsigned int ledStates[LEDLEN] = {1,2,4,8,4,2};
74unsigned int ledCounter = 0;
75unsigned char ledStatesIndex = 0;
76unsigned int ledStatesLow[2] = {1,2};
77unsigned int ledCounterLow = 0;
78unsigned char ledStatesIndexLow = 0;
79unsigned int ledStatesHigh[2] = {4,8};
80unsigned int ledCounterHigh = 0;
81unsigned char ledStatesIndexHigh = 0;
82////////////////////////
83
84////Ethernet Parameters////
85XEmac Emac;
86XEmac *InstancePtr = &Emac;
87static Xuint8 LocalAddress[XEM_MAC_ADDR_SIZE] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; //wired MAC address... just filler... not used
88static volatile int RxMutex;  /* Shared var used for receive sequencing */
89static volatile int TxMutex;  /* Shared var used for transmit sequencing */
90static XStatus ErrorCode;     /* Shared var set when the error handler is called */
91static XStatus RxStatus;      /* Shared var set when the recv handler is called */
92static Xuint32 RxFrameLength; /* Shared var set when the recv handler is called */
93////////////////////////////
94
95//Interrupt Controller Driver Instance
96static XIntc myIntc;
97
98////User Callback Pointers////
99//These the addresses pointed to by these variables are set by the
100//user via the callback registration functions
101void (*usr_upbutton) ();
102void (*usr_leftbutton) ();
103void (*usr_middlebutton) ();
104void (*usr_rightbutton) ();
105void (*usr_badPacketHandler) ();
106void (*usr_goodPacketHandler) ();
107void (*usr_timerHandler) ();
108void (*usr_emacHandler) ();
109//////////////////////////////
110
111////Buffer Pointers////
112//These allow DMA-enabled transfers to and from the user's memory space
113Macframe* rxPacket;
114Macframe* txPacket;
115
116void nullHandler(void* param){
117};
118
119
120/*WARPMAC_PHYINTERRUPTCLEAR - Lowers the interrupt line from the transceriver*/
121void warpmac_phyInterruptClear(){
122        alamouti_mac2phy_PktAck();
123        return;
124}
125
126/*EMACRX_INT_HANDLER - Handles the reception of packets from the emac core*/
127static void emacRx_int_handler(void *Callback) {
128        XEmac *EmacPtr = (XEmac *)Callback;
129        Xuint32 length = MY_XEM_MAX_FRAME_SIZE;
130
131        if(controlStruct.enableEthernetInt){
132                RxStatus = XEmac_FifoRecv(EmacPtr, txPacket->data, &length);
133                if(RxStatus != XST_SUCCESS){
134                        xil_printf("Error in Fifo Recv: %d\r\n", RxStatus);
135                        return;
136                }
137                RxMutex=1;
138                usr_emacHandler(RxMutex,length);
139        }
140        else{
141                RxMutex=0;
142        }
143
144        XIntc_Acknowledge(&myIntc,XPAR_OPB_INTC_0_ETHERNET_MAC_IP2INTC_IRPT_INTR);
145
146}
147
148/*EMACTX_INT_HANDLER - This handler is called when the emac is finished sending a packet*/
149static void emacTx_int_handler(void *Callback){
150        TxMutex=0;
151        rxPacket->isNew=0;
152}
153
154/*EMACERR_INT_HANDLER - This handler is called when there is a problem with the emac*/
155static void emacErr_int_handler(void *Callback, XStatus ErrCode){
156        xil_printf("ERROR IN EMAC #%d\r\n",ErrCode);
157}
158
159/*WARPMAC_INCREMENTLED - Every BLINKEVERY (in warpmac.h) times this function is called,
160the user LEDs will switch state. The end result is a visualization that looks like Kitt
161from Knightrider.*/
162void warpmac_incrementLED(){
163        if(ledCounter==0){
164                XGpio_mSetDataReg(XPAR_LEDS_4BIT_BASEADDR, 1, ledStates[ledStatesIndex]);
165                ledStatesIndex = (ledStatesIndex+1)%LEDLEN;
166        }
167        ledCounter = (ledCounter+1)%BLINKEVERY;
168}
169
170/*WARPMAC_INCREMENTLEDLOW - Much like WARPMAC_INCREMENTLED, but allows for independent
171control of the bottom two LEDs*/
172void warpmac_incrementLEDLow(){
173        if(ledCounterLow==0){
174                XGpio_mSetDataReg(XPAR_LEDS_4BIT_BASEADDR, 1, (ledStatesLow[ledStatesIndexLow]|ledStatesHigh[ledStatesIndexHigh]));
175                ledStatesIndexLow = (ledStatesIndexLow+1)%2;
176        }
177        ledCounterLow = (ledCounterLow+1)%BLINKEVERY;
178}
179
180/*WARPMAC_INCREMENTLEDHIGH - Much like WARPMAC_INCREMENTLED, but allows for independent
181control of the top two LEDs*/
182void warpmac_incrementLEDHigh(){
183        if(ledCounterHigh==0){
184                //xil_printf("%x\r\n", (ledStatesLow[ledStatesIndexLow]|ledStatesHigh[ledStatesIndexHigh]));
185                XGpio_mSetDataReg(XPAR_LEDS_4BIT_BASEADDR, 1, (ledStatesLow[ledStatesIndexLow]|ledStatesHigh[ledStatesIndexHigh]));
186                ledStatesIndexHigh = (ledStatesIndexHigh+1)%2;
187
188        }
189        ledCounterHigh = (ledCounterHigh+1)%BLINKEVERY;
190}
191
192
193/*TIMER_A_INT_HANDLER - interrupt handler for the first timer peripheral
194The timer interrupt handler gets called when a hardware timer set by the
195user expires. The user's callback is called upon the completion of this event */
196void timer_a_int_handler(void * baseaddr_p) {
197
198
199        /* Clear the timer interrupt */
200        ofdm_timer_clearInterrupt();
201        int baseaddr = (int) baseaddr_p;
202        controlStruct.timerEnabled = 0;
203        //Call User Function
204        usr_timerHandler(controlStruct.timerType);
205
206}
207
208
209/*rxPhyBad - interrupt handler for the receive PHY layer
210This function is the ISR for the RX physical layer peripheral.
211This function is only called if the packet fails CRC. The received
212packet is passed to the user's callback.*/
213void rxPhyBad(void *baseaddr_p) {
214
215        unsigned char header[24];
216        unsigned int numPayloadBytes;
217        int length;
218
219
220        alamouti_ofdmRx_copyHeader(header,24); //Copy just the header
221
222        unsigned int b = (unsigned int)header[18];
223        unsigned int a = (unsigned int)header[19];
224
225        numPayloadBytes = a*256 + b;//(*(unsigned short *)(0xFF101000+18));
226
227#ifdef DEBUG_PKT_PRINT
228                xil_printf("\r\n******************\r\nBAD:");
229                xil_printf(" (%x %x -> %d) ",a, b, numPayloadBytes);
230
231                int i;
232                for(i=0;i<24;i++)
233                {
234                        xil_printf("%x.",header[i]);
235                }
236
237                xil_printf("\r\n");
238#endif
239
240                usr_badPacketHandler(rxPacket);
241                alamouti_mac2phy_PktAck();
242}
243
244
245/*rxPhyGood - interrupt handler for the receive PHY layer
246This function is the ISR for the RX physical layer peripheral.
247This function is only called if the packet has no bit errors
248(i.e., the packet passes CRCs in the PHY). The function copies
249the contents from the PHY into a temporary buffer, which then
250gets converted to the custom frame structure that the MAC
251code understands. The received packet is passed to the
252user's callback.*/
253void rxPhyGood(void *baseaddr_p) {
254
255        if(rxPacket->isNew==0){
256                unsigned char header[24];
257                unsigned int numPayloadBytes;
258                int length;
259                alamouti_ofdmRx_copyHeader(header,24); //Copy just the header
260                rxPacket->pktType = header[13];
261                rxPacket->destAddr[0] = header[3];
262                rxPacket->destAddr[1] = header[2];
263                rxPacket->destAddr[2] = header[1];
264                rxPacket->destAddr[3] = header[0];
265                rxPacket->destAddr[4] = header[7];
266                rxPacket->destAddr[5] = header[6];
267                rxPacket->srcAddr[0] = header[5];
268                rxPacket->srcAddr[1] = header[4];
269                rxPacket->srcAddr[2] = header[11];
270                rxPacket->srcAddr[3] = header[10];
271                rxPacket->srcAddr[4] = header[9];
272                rxPacket->srcAddr[5] = header[8];
273                rxPacket->pktRev = header[15];
274
275                unsigned int b = (unsigned int)header[18];
276                unsigned int a = (unsigned int)header[19];
277
278                numPayloadBytes = a*256 + b;//(*(unsigned short *)(0xFF101000+18));
279
280                        if(controlStruct.sequenceVec[rxPacket->srcAddr[5]].sequenceNumber[1] == header[16]){
281                                controlStruct.packetDupe=1;     //if sequencing is enabled, this will be used to keep the packet from
282                                                                                        //being sent over ethernet
283                        }
284                        else{
285                                controlStruct.packetDupe=0;
286                                controlStruct.sequenceVec[rxPacket->srcAddr[5]].sequenceNumber[1] = header[16];
287                        }
288
289#ifdef DEBUG_PKT_PRINT
290                        xil_printf("\r\n******************\r\nGOOD:");
291                        xil_printf(" (%d) ",numPayloadBytes);
292                        xil_printf(" (%d) ",ofdm_txrx_alamouti_ReadReg_Rx_packet_done(OFDM_BASEADDR));
293
294                        int i;
295                        for(i=0;i<24;i++)
296                        {
297                                xil_printf("%x.",header[i]);
298                        }
299
300                        xil_printf("\r\n");
301#endif
302
303                        rxPacket->length = numPayloadBytes - 24 - 4; //4 bytes for checksum
304                        if(rxPacket->length < 0 || rxPacket->length>MY_XEM_MAX_FRAME_SIZE){
305                                rxPacket->length=0;
306                        }
307                        usr_goodPacketHandler(rxPacket);
308
309        }
310
311
312        alamouti_mac2phy_PktAck();
313
314}
315
316/*PB_INT_HANDLER - interrupt handler for the pushbuttons on the WARP board. This is a low-priority
317interrupt because it is primarily used for debugging purposes. The various user callbacks are
318executed, depending upon which button was depressed.*/
319void pb_int_handler(void *baseaddr_p) {
320
321        Xuint32 dsr;
322        XStatus stat;
323        char lock;
324
325        dsr = XGpio_mGetDataReg(XPAR_PUSH_BUTTONS_4BIT_BASEADDR, 2);
326        switch(dsr) {
327
328                case 0x01:
329                        usr_middlebutton();
330                        break;
331
332                case 0x02:
333                        usr_rightbutton();
334                        break;
335
336                case 0x08:
337                        usr_upbutton();
338                        break;
339                case 0x04:
340                        usr_leftbutton();
341                        break;
342
343                default : {
344                }
345
346        }
347        XGpio_InterruptClear(&Gpio, 0x3); // clear the interrupt
348}
349
350/*WARPMAC_CLEARTIMER - This function stops the ofdm_timer. Additionally it
351will return the amount of time remaining before expiration.*/
352int warpmac_clearTimer(){
353        int time;
354        time = ofdm_timer_timeLeft();
355        ofdm_timer_stop();
356        controlStruct.currBackoff=0;
357        return time;
358}
359
360/*WARPMAC_SETTIMERVAL - This function sets the ofdm_timer to countdown for
361a given number of clock cycles.*/
362void warpmac_setTimerVal(Xuint32 clocks){
363        ofdm_timer_setVal(clocks);
364}
365
366/*WARPMAC_STARTTIMER - This function starts the ofdm_timer in either
367a CSMA or non-CSMA mode.*/
368void warpmac_startTimer(unsigned char mode){
369        ofdm_timer_setMode(mode);
370        ofdm_timer_start();
371}
372
373/*RANDNUM- generates a uniform random value between [0,N-1]*/
374int randNum(int N){
375        return rand() >> (32-(N+6));
376
377/*      int ans;
378        int temp;
379        temp = rand();
380        ans = temp>>(32-(N+6));
381        return ans;
382*/
383}
384
385/*WARPMAC_CARRIERSENSE- returns a value corresponding to the instantaneous channel condition.*/
386unsigned int warpmac_carrierSense(){
387        return ofdm_pktDetector_mimo_ReadReg_pktDet_idleDifs(PKTDET_BASEADDR);
388}
389
390/*SETTIMER- function is responsible for enabling the hardware timer peripherals*/
391int warpmac_setTimer(int type){
392        unsigned int setTime;
393        int myRandNum;
394        int retval;
395        switch(type) {
396                case TIMEOUT:
397                        controlStruct.timerType=TIMEOUT;
398                        setTime = controlStruct.timeout*40;
399                        warpmac_setTimerVal(setTime);
400                        warpmac_startTimer(DISABLECSMA);
401                        return 0;
402                        break;
403
404                case BACKOFF:
405                        controlStruct.timerType=BACKOFF;
406                        myRandNum = randNum(controlStruct.currBackoff);
407                        setTime = myRandNum*controlStruct.slotTime*40;
408                        if(controlStruct.currBackoff < controlStruct.maxBackoff){
409                                /*Note: Currently, I never decrement a backoff... I only reset it upon the next frame. Technically, CSMA-CA
410                                should decrement the window under certain circumstances (check the 802.11 standard for details)*/
411                                controlStruct.currBackoff = controlStruct.currBackoff + 1;
412                        }
413
414                                /* Set the reset value of the timer (seconds * 50,000,000) */
415                                if(setTime != 0){
416                                        warpmac_setTimerVal(setTime);
417                                        warpmac_startTimer(ENABLECSMA);
418                                        return 0;
419                                }
420
421                                if(setTime == 0){
422                                        usr_timerHandler(controlStruct.timerType);
423                                }
424                                break;
425
426        }
427}
428
429
430/*WARPMAC_INIT- initializes the framework and all hardware peripherals.*/
431int warpmac_init() {
432
433        usr_upbutton = nullHandler;
434        usr_leftbutton = nullHandler;
435        usr_middlebutton = nullHandler;
436        usr_rightbutton = nullHandler;
437        usr_badPacketHandler = nullHandler;
438        usr_goodPacketHandler = nullHandler;
439
440        xil_printf("Initializing WARPMAC...\r\n");
441
442        xil_printf("    Initializing Ethernet...");
443
444        /////////////////////////////////Set up ACKMAC////////////////////////////////////////////////////
445
446        xil_printf("    Initializing controlStruct...");
447
448        controlStruct.enableSequencing = 0;
449        controlStruct.packetDupe=0;
450        controlStruct.mySequenceNum.sequenceNumber[1] = 0;
451        controlStruct.maxReSend = 4;
452        controlStruct.currBackoff = 0;
453        controlStruct.timerEnabled = 0;
454        controlStruct.maxBackoff = 5;
455        xil_printf("complete!\r\n");
456
457        int retval;
458
459        xil_printf("    Initializing Interrupts...");
460        // Initialize the LEDs
461        XGpio_mSetDataReg(XPAR_LEDS_4BIT_BASEADDR, 1, 0x0004);
462
463        // Initialize the push buttons
464        XGpio_Initialize(&Gpio, XPAR_PUSH_BUTTONS_4BIT_DEVICE_ID);
465
466        XGpio_mSetDataDirection(XPAR_PUSH_BUTTONS_4BIT_BASEADDR, 1, 0x3);
467        // Enable interrupts for the push buttons
468        XGpio_InterruptEnable(&Gpio, XGPIO_IR_CH1_MASK);
469
470        // Enable global interrupts. Both this and above line necessary to enable interrupts
471        XGpio_InterruptGlobalEnable(&Gpio);
472
473
474        XIntc_Initialize(&myIntc, XPAR_OPB_INTC_0_DEVICE_ID);
475
476
477        XIntc_SetIntrSvcOption(XPAR_OPB_INTC_0_BASEADDR,XIN_SVC_ALL_ISRS_OPTION); //keeps system from "missing" interrupts...
478                                                                                                                                                          //services all queued interrupts
479
480
481
482        XIntc_Connect(&myIntc, XPAR_OPB_INTC_0_PUSH_BUTTONS_4BIT_IP2INTC_IRPT_INTR,(XInterruptHandler)pb_int_handler, NULL);
483        XIntc_Connect(&myIntc, XPAR_OPB_INTC_0_OFDM_TXRX_ALAMOUTI_OPBW_0_RX_INT_GOODPKT_INTR,(XInterruptHandler)rxPhyGood, NULL);
484        XIntc_Connect(&myIntc, XPAR_OPB_INTC_0_OFDM_TXRX_ALAMOUTI_OPBW_0_RX_INT_BADPKT_INTR,(XInterruptHandler)rxPhyBad, NULL);
485        XIntc_Connect(&myIntc, XPAR_OPB_INTC_0_OFDM_TIMER_OPBW_0_TIMEREXPIRE_INTR,(XInterruptHandler)timer_a_int_handler, NULL);
486        XIntc_Connect(&myIntc, XPAR_OPB_INTC_0_ETHERNET_MAC_IP2INTC_IRPT_INTR,(XInterruptHandler) XEmac_IntrHandlerFifo, &Emac);
487
488
489
490        XIntc_Start(&myIntc, XIN_REAL_MODE);
491        XIntc_Enable(&myIntc, XPAR_OPB_INTC_0_PUSH_BUTTONS_4BIT_IP2INTC_IRPT_INTR);
492        XIntc_Enable(&myIntc, XPAR_OPB_INTC_0_OFDM_TXRX_ALAMOUTI_OPBW_0_RX_INT_GOODPKT_INTR);
493        XIntc_Enable(&myIntc, XPAR_OPB_INTC_0_OFDM_TXRX_ALAMOUTI_OPBW_0_RX_INT_BADPKT_INTR);
494        XIntc_Enable(&myIntc, XPAR_OPB_INTC_0_OFDM_TIMER_OPBW_0_TIMEREXPIRE_INTR);
495        XIntc_Enable(&myIntc, XPAR_OPB_INTC_0_ETHERNET_MAC_IP2INTC_IRPT_INTR);
496
497
498
499
500
501        xil_printf("Setting up exceptions...\r\n");
502        XExc_Init();
503        XExc_RegisterHandler(XEXC_ID_NON_CRITICAL_INT,(XExceptionHandler)XIntc_InterruptHandler,&myIntc);
504        XExc_mEnableExceptions(XEXC_NON_CRITICAL);
505
506
507
508        xil_printf("complete!\r\n");
509        /////////////////////////////
510
511
512        /////////////////////////ETHERNET///////////////////////
513        int i,l;
514        XStatus Status;
515        Xuint32 Options;
516        Xuint16 DeviceId = XPAR_ETHERNET_MAC_DEVICE_ID;
517
518        /*
519     * Initialize the XEmac component. The device ID chosen should be
520     * configured without DMA (see the xemac_g.c file)
521     */
522    Status = XEmac_Initialize(InstancePtr, DeviceId);
523    if (Status != XST_SUCCESS)
524    {
525         xil_printf("Failed to initialize EMAC\r\n");
526        return XST_FAILURE;
527    }
528
529    /*
530     * Run self-test on the device, which verifies basic sanity of the
531     * device and the driver.
532     */
533    Status = XEmac_SelfTest(InstancePtr);
534    if (Status != XST_SUCCESS)
535    {
536                xil_printf("Self Test Failed\r\n");
537        return XST_FAILURE;
538    }
539
540    /*
541     * Configure the device to be promiscuous
542     */
543        //
544    //Options = XEmac_GetOptions(InstancePtr);
545    Options = (XEM_INSERT_FCS_OPTION |
546                           XEM_INSERT_PAD_OPTION |
547                           XEM_UNICAST_OPTION |
548                           XEM_BROADCAST_OPTION |
549                           //XEM_POLLED_OPTION|
550                           //XEM_OVWRT_ADDR_OPTION|
551                           XEM_PROMISC_OPTION|
552                           XEM_STRIP_PAD_FCS_OPTION);
553
554    Status = XEmac_SetOptions(InstancePtr, Options);
555    if (Status != XST_SUCCESS)
556    {
557         xil_printf("Failed to set options of EMAC\r\n");
558        return XST_FAILURE;
559    }
560
561    /*
562     * Set the MAC Addrees
563     */
564
565    Status = XEmac_SetMacAddress(InstancePtr, LocalAddress); //Note: Even though we are setting a MAC
566                                                                                                                         //Address for the node, it is in promiscuous
567                                                                                                                         //mode
568    if (Status != XST_SUCCESS)
569    {
570         xil_printf("Failed to set MAC of EMAC\r\n");
571        return XST_FAILURE;
572    }
573
574    /*
575     * Start the device, which enables the transmitter and receiver
576     */
577        XEmac_SetFifoSendHandler(InstancePtr, InstancePtr,
578                              (XEmac_FifoHandler)emacTx_int_handler);
579    XEmac_SetFifoRecvHandler(InstancePtr, InstancePtr,
580                                                         (XEmac_FifoHandler)emacRx_int_handler);
581    XEmac_SetErrorHandler(InstancePtr, InstancePtr,
582                                                  (XEmac_ErrorHandler)emacErr_int_handler);
583
584    Status = XEmac_Start(InstancePtr);
585    if (Status != XST_SUCCESS)
586    {
587         xil_printf("Failed to start EMAC\r\n");
588        return XST_FAILURE;
589    }
590        xil_printf("complete!\r\n");
591
592        RxMutex=0;
593        TxMutex=0;
594
595        ///////////////////////////////////////////////////////////////////////////////////////////////////
596
597        ////////////////////////////////////SET UP RADIO and PHY///////////////////////////////////////////
598
599        xil_printf("    Initializing Radio Transmitter...");
600
601        warpmac_CalibrateTxDCO();
602
603        //Setup the radio controller
604        WarpRadio_v1_Reset((unsigned int *)XPAR_RADIO_CONTROLLER_0_BASEADDR);
605        WarpRadio_v1_TxLpfCornFreqCoarseAdj( 0x1, FIRST_RADIO | SECOND_RADIO);
606//      WarpRadio_v1_TxLpfCornFreqCoarseAdj( 0x1, FIRST_RADIO | SECOND_RADIO);
607
608
609        //Finally turn on the power amplifier
610        WarpRadio_v1_24AmpEnable(FIRST_RADIO | SECOND_RADIO);
611        WarpRadio_v1_SetTxTiming(FIRST_RADIO, 50, 0, 0, 0);
612        WarpRadio_v1_SetTxTiming(SECOND_RADIO, 50, 255, 0, 0);
613        WarpRadio_v1_SetTxGainTiming(FIRST_RADIO | SECOND_RADIO, 0x3F, 0xF, 2);
614        WarpRadio_v1_BaseBandTxGain(0x0, FIRST_RADIO | SECOND_RADIO);
615
616        xil_printf("complete!\r\n");
617        //**** End Radio Transmitter Initialization ****
618
619        //**** Begin Radio Receiver Initialization ****
620
621        xil_printf("    Initializing Radio Receiver...");
622
623        //Enable AGC control of receive gains
624        WarpRadio_v1_SoftwareRxGainControl(0,FIRST_RADIO | SECOND_RADIO);
625        /* Use these functions to override AGC in software */
626        //WarpRadio_v1_SoftwareRxGainControl(1,FIRST_RADIO | SECOND_RADIO);
627        //WarpRadio_v1_RxLNAGainControl(0x3,FIRST_RADIO | SECOND_RADIO);
628        //WarpRadio_v1_RxVGAGainControl(0x10,FIRST_RADIO | SECOND_RADIO);
629
630        WarpRadio_v1_RxLpfCornFreqCoarseAdj(0x0, FIRST_RADIO | SECOND_RADIO);
631//      WarpRadio_v1_RxLpfCornFreqCoarseAdj(0x1, FIRST_RADIO | SECOND_RADIO);
632
633        xil_printf("complete\r\n");
634        //**** End Radio Receiver Initialization ****
635
636
637        //**** Begin OFDM Transmitter Initialization ****
638
639        xil_printf("    Initializing OFDM Transmitter...");
640
641        #define TX_FFT_SCALING_STAGE1 1
642        #define TX_FFT_SCALING_STAGE2 2
643        #define TX_FFT_SCALING_STAGE3 3
644
645        //Zero out the modulation RAM - only transmit pilots
646        //bzero((unsigned int *)(XPAR_OFDM_TXRX_ALAMOUTI_OPBW_0_BASEADDR+ofdm_TxRx_alamouti_SMWO_TxModulation_OFFSET), (64/2)*3);
647
648        alamouti_ofdmTx_init();
649        alamouti_ofdmTx_setFFTScaling((unsigned int)(16*TX_FFT_SCALING_STAGE1 + 4*TX_FFT_SCALING_STAGE2 + 1*TX_FFT_SCALING_STAGE3));
650        alamouti_ofdmTx_setPilot1Index((7 + ((64-7)<<16) ));
651        alamouti_ofdmTx_setPilot1Value(0x8000);//c000 8000
652        alamouti_ofdmTx_setPilot2Index((21 + ((64-21)<<16)));
653        alamouti_ofdmTx_setPilot2Value(0x7fff);  //3fff 7fff
654        alamouti_ofdmTx_setRandom(0);
655
656        #ifdef DEBUG_PKT_PRINT
657        xil_printf("numTxBytes: %d\r\n",ofdm_txrx_alamouti_ReadReg_Tx_NumPayloadBytes(XPAR_OFDM_TXRX_ALAMOUTI_OPBW_0_BASEADDR));
658        #endif
659
660        alamouti_ofdmTx_setNumSyms(numTrainingSyms + (numBaseRate*256));
661        alamouti_ofdmTx_setPreambleScaling(0x42FF);//42FF);//0x40FF); //7fff
662        alamouti_ofdmTx_setControlBits(
663                (2000 << 16) | //Delay 2nd transmit by 1000 25MHz cycles
664                (0 << 9) | //Transmit block A first
665                (0 << 8) | //Disable retransmissions
666                (2 << 4) | //Shift antenna B's preamble
667                /*TX_RANDOM_MODE |*/
668                /*TX_DISABLE_ANTB_PREAMBLE |*/
669                TX_PILOT_SCRAMBLING
670                );
671        alamouti_ofdmTx_enable();
672
673        //**** End OFDM Transmitter Initialization ****
674
675        //**** Begin OFDM Receiver Initialization ****
676
677        xil_printf("    Initializing OFDM Receiver...");
678        #define FFT_SCALING_STAGE1 0    //1
679        #define FFT_SCALING_STAGE2 1    //2
680        #define FFT_SCALING_STAGE3 1    //1
681
682                alamouti_ofdmRx_init();
683
684                //Scaling options:
685                //268439552 -> 2
686                //201329664 -> 1.5
687                //134219776 -> 1
688                //33554944 -> 0.25
689                //67109888 -> 0.5
690                //100664832 -> 0.75
691                //114086809 -> 0.85
692//              unsigned int myScaling = 67109888;//201329664;//(2048 + 2048<<16);
693                unsigned int myScaling = 134219776;
694
695                alamouti_ofdmRx_setFFTScaling((unsigned int)(16*FFT_SCALING_STAGE1 + 4*FFT_SCALING_STAGE2 + 1*FFT_SCALING_STAGE3));
696                alamouti_ofdmRx_setFFTWindowOffset(INIT_RXFFTOFSET); //8
697                alamouti_ofdmRx_setRxScaling(myScaling);//134219776);//(unsigned int)((unsigned int)2048 + ((unsigned int)2048*(2^16))));//2048 + 2048<<16);//2048 + 2048*2^16);//134219776);//0x1e66 + (0x1e66<<16)); //.5 in Fix_16_11
698                alamouti_ofdmRx_setCorrThresh(0x60);
699                alamouti_ofdmRx_setEnergyThresh(0x0);
700                alamouti_ofdmRx_setLongCorrParams(251-16  + (2500*65536)); //251 2500
701                alamouti_ofdmRx_setPktDetDly(80); //+43, //52
702                alamouti_ofdmRx_setNumOFDMSyms(numTrainingSyms + (numBaseRate*65536));
703
704//              alamouti_ofdmRx_setByteNums( (unsigned int)(24 + (16<<16) + (17<<24) ));
705                alamouti_ofdmRx_setByteNums( (unsigned int)(24 + (18<<16) + (19<<24) ));
706//              alamouti_ofdmRx_setByteNums( (unsigned int)(24 + (22<<16) + (23<<24) ));
707
708                alamouti_ofdmRx_setCFODly(16);
709
710                //ofdm_TxRx_alamouti_WriteReg_Rx_PktDet_Delay(XPAR_OFDM_TXRX_ALAMOUTI_OPBW_0_BASEADDR, 43 + (12<<7) + (CFODlyval<<16));
711
712                alamouti_ofdmRx_setCFO_A_KP(INIT_A_KPVAL);
713
714                alamouti_ofdmRx_setCFO_B_KI(INIT_B_KIVAL);
715                alamouti_ofdmRx_setCFO_B_KP(INIT_B_KPVAL);
716
717                alamouti_ofdmRx_setPNTrack_K(INIT_PN_KVAL);
718                alamouti_ofdmRx_setPNTrack_Kalpha(INIT_PN_KAlphaVAL);
719                alamouti_ofdmRx_setPNTrack_Kbeta(INIT_PN_KBetaVAL);
720                alamouti_ofdmRx_setPNTrack_Kgamma(INIT_PN_KGammaVAL);
721
722                alamouti_ofdmRx_setOptions(
723                                                                //RESET_BER |
724                                                                REQ_LONG_CORR |
725                                                                DYNAMC_PKT_LENGTHS |
726                                                                REQ_TWO_LONG_CORR |
727                                                                REQ_SHORT_CORR |
728                                                                //BYPASS_CARR_REC |
729                                                                //CFO_USE_LTS |
730                                                                //CFO_USE_LONGCORR |
731                                                                USE_PILOT_ARCTAN |
732                                                                SWITCHING_DIVERSITY |
733                                                                QUAD_LONGCORR_EN |
734                                                                EXT_PKT_DETECT,
735                                                                INTR_BAD_PKTS | INTR_GOOD_PKTS
736                                                                );
737                alamouti_ofdmRx_enable();
738
739                //Configure Tx/Rx for QPSK
740                //All three entries must match for the Alamouti model
741                //warpmac_set_modulation(mod_fullRate, mod_fullRate, mod_fullRate);
742
743                xil_printf("complete!\r\n");
744                //**** End OFDM Receiver Initialization ****
745
746
747                xil_printf("    Initializing AGC...");
748
749                WarpRadio_v1_RxHpSoftControlDisable(FIRST_RADIO | SECOND_RADIO);
750                //IMPORTANT!!!?
751                WarpRadio_v1_RxHighPassCornerFreq(1, FIRST_RADIO | SECOND_RADIO);
752
753                ofdm_AGC_Initialize(agcnoiseEst);
754                ofdm_AGC_setNoiseEstimate(agcnoiseEst);
755                ofdm_AGC_FiltSel(1);
756                ofdm_AGC_SetDCO(1); //1
757                ofdm_AGC_SetTarget(agctarget); //-7
758                ofdm_AGC_Reset();
759                xil_printf("complete!\r\n");
760                ////////////////////////////////////////////////////////////////
761                ////////////////SET UP RSSI PACKET DETECTOR/////////////////////
762                xil_printf("    Initializing Packet Detection...");
763
764                ofdm_pktDetector_mimo_WriteReg_csma_enableBusy(PKTDET_BASEADDR, 1);
765                ofdm_pktDetector_mimo_WriteReg_csma_enableIdle(PKTDET_BASEADDR, 1);
766                ofdm_pktDetector_mimo_WriteReg_pktDet_masterReset(PKTDET_BASEADDR, 1);
767                ofdm_pktDetector_mimo_WriteReg_pktDet_detectionMask(PKTDET_BASEADDR, 3); //3 = radios slot 2 and 3
768//              ofdm_pktDetector_mimo_WriteReg_pktDet_detectionMask(PKTDET_BASEADDR, 2); //2 = radio slot 3
769//              ofdm_pktDetector_mimo_WriteReg_pktDet_detectionMask(PKTDET_BASEADDR, 1); //1 = radio slot 2
770                ofdm_pktDetector_mimo_WriteReg_pktDet_detectionMode(PKTDET_BASEADDR, 1); //0 = AND, 1 = OR
771                ofdm_pktDetector_mimo_WriteReg_pktDet_resetDuration(PKTDET_BASEADDR, 32);
772                ofdm_pktDetector_mimo_WriteReg_pktDet_avgLen(PKTDET_BASEADDR, 16);
773                ofdm_pktDetector_mimo_WriteReg_pktDet_avgThresh(PKTDET_BASEADDR, 7000);
774                ofdm_pktDetector_mimo_WriteReg_csma_avgThresh(PKTDET_BASEADDR, 16000);
775                ofdm_pktDetector_mimo_WriteReg_csma_difsPeriod(PKTDET_BASEADDR, 625);
776                ofdm_pktDetector_mimo_WriteReg_pktDet_masterReset(PKTDET_BASEADDR, 0);
777                ofdm_pktDetector_mimo_WriteReg_pktDet_reset(PKTDET_BASEADDR, 0);
778
779                xil_printf("complete!\r\n");
780                ////////////////////////////////////////////////////////////////
781
782                WarpRadio_v1_RxEnable(FIRST_RADIO | SECOND_RADIO);
783
784return 0;
785
786}
787
788
789void warpmac_pollEthernet(int* callback()){
790        xil_printf("Deprecated Function\r\n");
791}
792
793/*WARPMAC_SENDETHERNET- Pushes the given Macframe over ethernet*/
794void warpmac_sendEthernet(Macframe* packet){
795
796        if(!((controlStruct.enableSequencing) && (controlStruct.packetDupe)) && TxMutex==0){
797                unsigned int length;
798                length = (packet->length)-4;
799
800                XEmac_FifoSend(InstancePtr, OFDM_TXRX_ALAMOUTI_RXPKTBUFFER_BASEADDR+24, length);
801
802                TxMutex=1;
803                rxPacket->isNew=1;
804
805        }
806
807        TxMutex = 0;
808}
809
810
811/*WARPMAC_SENDOFDM- performs the conversion from the packet structure to the byte array and
812sends the packet over the air*/
813int warpmac_sendOfdm(Macframe* packet){
814    int i;
815    unsigned int numPayloadBytes;
816    unsigned int Npld;
817        unsigned char header[24];
818
819        ofdm_pktDetector_mimo_WriteReg_pktDet_reset(PKTDET_BASEADDR, 1);
820
821// From multiplexing MIMO model
822//      Npld = ((packet->length + 4 + (6*controlStruct.mod_fullRateA-1))/(6*controlStruct.mod_fullRateA)) * (sisoMode+1);
823
824
825        Npld = 2 + ((packet->length + 4 + (6*mod_fullRate-1))/(6*mod_fullRate));
826        Npld = Npld + (Npld%2);
827
828        numPayloadBytes = 24 + packet->length + 4;
829
830        alamouti_ofdmTx_setNumBytes(numPayloadBytes);
831        alamouti_ofdmTx_setNumSyms(numTrainingSyms + (numBaseRate*256) + (Npld*65536));
832
833        header[0]= (packet->destAddr[3]);
834        header[1]= (packet->destAddr[2]);
835        header[2]= (packet->destAddr[1]);
836        header[3]= (packet->destAddr[0]);
837        header[4]= (packet->srcAddr[1]);
838        header[5]= (packet->srcAddr[0]);
839        header[6]= (packet->destAddr[5]);
840        header[7]= (packet->destAddr[4]);
841        header[8]= (packet->srcAddr[5]);
842        header[9]= (packet->srcAddr[4]);
843        header[10]= (packet->srcAddr[3]);
844        header[11]= (packet->srcAddr[2]);
845        header[12]= 0;
846        header[13]= packet->pktType;
847        header[14]= mod_fullRate;
848        header[15]= packet->pktRev;  //version/mode/revision
849        header[16]= (controlStruct.mySequenceNum.sequenceNumber[1]); //0
850        header[17]= 0;
851        header[18]= (0xFF & numPayloadBytes); //less significant byte of total length
852        header[19]= (0xFF & (numPayloadBytes >> 8)); //more significant byte of total length
853        header[20]= 0;
854        header[21]= 0;
855        header[22]= 0;
856        header[23]= 0;
857
858        alamouti_ofdmTx_copyHeader(header,(size_t)24);
859        alamouti_ofdmTx_copyPayload(packet->data, (size_t)(packet->length) );
860
861#ifdef DEBUG_PKT_PRINT
862        xil_printf("\r\n******************\r\nTX:");
863        xil_printf(" (%d - %d) ",numPayloadBytes, Npld);
864
865        for(i=0;i<24;i++)
866        {
867                xil_printf("%x.",header[i]);
868        }
869
870        xil_printf("\r\n");
871#endif
872
873        alamouti_mac2phy_pktTx(TXBLOCK, FIRST_RADIO | SECOND_RADIO);
874
875        WarpRadio_v1_RxEnable(FIRST_RADIO | SECOND_RADIO);
876
877        if(globalReset==0) ofdm_pktDetector_mimo_WriteReg_pktDet_reset(PKTDET_BASEADDR, 0);
878
879        return 0;
880}
881
882/*WARPMAC_SETUPBUTTONHANDLER- attaches user callback to up button*/
883void warpmac_setUpButtonHandler(void(*handler)()){
884        usr_upbutton = handler;
885}
886
887/*WARPMAC_SETLEFTBUTTONHANDLER- attaches user callback to left button*/
888void warpmac_setLeftButtonHandler(void(*handler)()){
889        usr_leftbutton = handler;
890}
891
892/*WARPMAC_SETRIGHTBUTTONHANDLER- attaches user callback to right button*/
893void warpmac_setRightButtonHandler(void(*handler)()){
894        usr_rightbutton = handler;
895}
896
897/*WARPMAC_SETMIDDLEBUTTONHANDLER- attaches user callback to middle button*/
898void warpmac_setMiddleButtonHandler(void(*handler)()){
899        usr_middlebutton = handler;
900}
901
902/*WARPMAC_SETTIMERHANDLER- attaches user callback to timer*/
903void warpmac_setTimerHandler(void(*handler)()){
904   usr_timerHandler = handler;
905}
906
907
908
909/*WARPMAC_SETEMACHANDLER- attaches user callback to ethernet*/
910void warpmac_setEmacHandler(void(*handler)()){
911        usr_emacHandler = handler;
912}
913
914/*WARPMAC_SETGOODPACKETHANDLER- attaches user callback to good packet interrupt*/
915void warpmac_setGoodPacketHandler(void(*handler)()){
916        usr_goodPacketHandler = handler;
917}
918
919/*WARPMAC_SETBADPACKETHANDLER- attaches user callback to bad packet interrupt*/
920void warpmac_setBadPacketHandler(void(*handler)()){
921        usr_badPacketHandler = handler;
922}
923
924
925/*WARPMAC_INCREMENTRESEND- increments the resend counter for the current transmit.
926Additionally, it will free the payload when the maximum number of retransmissions has
927occured.*/
928int warpmac_incrementResend(Macframe* packet){
929        int status = 1;
930        packet->currReSend = ( packet->currReSend+1)%((controlStruct.maxReSend)+1); //increment currReSend and wrap around max
931        if( packet->currReSend == 0) { //if reSend wraps around, the packet will be dropped
932                status = 0;
933                //buffree(mbuftACK,packet->data);
934                controlStruct.currBackoff=0;
935                packet->isNew = 0;
936        }
937        return status;
938}
939
940
941/*WARPMAC_ALLOCATEPAYLOAD- readies a Macframe for transmission. This includes
942allocating memory for the payload and setting Macframe parameters.*/
943int warpmac_allocatePayload(Macframe* packet,unsigned int length){
944        xil_printf("Deprecated Function\r\n");
945}
946
947/*WARPMAC