?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik /******************************************************************************
2  
3 MRF24WB0M Driver Medium Access Control (MAC) Layer
4 Module for Microchip TCP/IP Stack
5 -Provides access to MRF24WB0M WiFi controller
6 -Reference: MRF24WB0M Data sheet, IEEE 802.11 Standard
7  
8 *******************************************************************************
9 FileName: WFMac.c
10 Dependencies: TCP/IP Stack header files
11 Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F, PIC32
12 Compiler: Microchip C32 v1.10b or higher
13 Microchip C30 v3.22 or higher
14 Microchip C18 v3.34 or higher
15 Company: Microchip Technology, Inc.
16  
17 Software License Agreement
18  
19 Copyright (C) 2002-2010 Microchip Technology Inc. All rights reserved.
20  
21 Microchip licenses to you the right to use, modify, copy, and distribute:
22 (i) the Software when embedded on a Microchip microcontroller or digital
23 signal controller product ("Device") which is integrated into
24 Licensee's product; or
25 (ii) ONLY the Software driver source files ENC28J60.c, ENC28J60.h,
26 ENCX24J600.c and ENCX24J600.h ported to a non-Microchip device used in
27 conjunction with a Microchip ethernet controller for the sole purpose
28 of interfacing with the ethernet controller.
29  
30 You should refer to the license agreement accompanying this Software for
31 additional information regarding your rights and obligations.
32  
33 THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
34 KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY
35 OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
36 NON-INFRINGEMENT. IN NO EVENT SHALL MICROCHIP BE LIABLE FOR ANY INCIDENTAL,
37 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST
38 OF PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS BY
39 THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), ANY CLAIMS
40 FOR INDEMNITY OR CONTRIBUTION, OR OTHER SIMILAR COSTS, WHETHER ASSERTED ON
41 THE BASIS OF CONTRACT, TORT (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR
42 OTHERWISE.
43  
44  
45 Author Date Comment
46 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
47 Michael Palladino 10/13/07 Original
48 KO 31 Oct 2008 Port to PIC24F and PIC32 for TCP/IP stack v4.52
49 KH 19 Jun 2009 Modified MACMemCopyAsync to support TCB to TCB copy
50 ******************************************************************************/
51  
52 /*
53 *********************************************************************************************************
54 * INCLUDES
55 *********************************************************************************************************
56 */
57  
58 #include "TCPIP Stack/WFMac.h"
59  
60 #if defined(WF_CS_TRIS)
61  
62 #include "TCPIP Stack/TCPIP.h"
63  
64  
65 /*
66 *********************************************************************************************************
67 * DEFINES
68 *********************************************************************************************************
69 */
70  
71 /* used for assertions */
72 #ifdef WF_DEBUG
73 #define WF_MODULE_NUMBER WF_MODULE_WF_MAC
74 #endif
75  
76 #define SNAP_VAL (0xaa)
77 #define SNAP_CTRL_VAL (0x03)
78 #define SNAP_TYPE_VAL (0x00)
79  
80 #define ETHER_IP (0x00)
81 #define ETHER_ARP (0x06)
82  
83 #if defined( __PIC32MX__ )
84 #define IPL_MASK ((UINT32)0x3f << 10)
85 #endif
86  
87 #define SNAP_SIZE (6)
88  
89 #define ENC_PREAMBLE_SIZE (sizeof(ENC_PREAMBLE))
90 #define ENC_PREAMBLE_OFFSET (10)
91  
92 #define WF_RX_PREAMBLE_SIZE (sizeof(tWFRxPreamble))
93 #define WF_TX_PREAMBLE_OFFSET (0)
94  
95 #define WF_TX_PREAMBLE_SIZE (sizeof(tWFTxPreamble))
96  
97 #define MCHP_DATA_PACKET_SIZE (4 + MAX_PACKET_SIZE + 4)
98  
99 //============================================================================
100 // Rx/Tx Buffer Constants
101 // Used to correlate former Ethernet packets to MRF24WB0M packets.
102 //============================================================================
103 #define ENC_RX_BUF_TO_RAW_RX_BUF_ADJUSTMENT ((RXSTART + ENC_PREAMBLE_SIZE) - (ENC_PREAMBLE_OFFSET + WF_RX_PREAMBLE_SIZE))
104 #define ENC_TX_BUF_TO_RAW_TX_BUF_ADJUSTMENT ((TXSTART + WF_TX_PREAMBLE_SIZE) - (WF_TX_PREAMBLE_OFFSET + WF_TX_PREAMBLE_SIZE))
105 #define ENC_TCB_BUF_TO_RAW_SCRATCH_BUF_ADJUSTMENT (BASE_TCB_ADDR)
106  
107 //============================================================================
108 // RAW Constants
109 //============================================================================
110 #define ENC_RD_PTR_ID (0)
111 #define ENC_WT_PTR_ID (1)
112  
113  
114 /*
115 *********************************************************************************************************
116 * LOCAL MACROS
117 *********************************************************************************************************
118 */
119  
120  
121 /*
122 *********************************************************************************************************
123 * LOCAL DATA TYPES
124 *********************************************************************************************************
125 */
126  
127 typedef struct
128 {
129 UINT8 type;
130 UINT8 subType;
131 } tRxPreamble;
132  
133 /* A header appended at the start of all RX frames by the hardware */
134 typedef struct _ENC_PREAMBLE
135 {
136 WORD NextPacketPointer;
137 RXSTATUS StatusVector;
138 MAC_ADDR DestMACAddr;
139 MAC_ADDR SourceMACAddr;
140 WORD_VAL Type;
141 } ENC_PREAMBLE;
142  
143 typedef struct
144 {
145 UINT8 snap[SNAP_SIZE];
146 MAC_ADDR DestMACAddr;
147 MAC_ADDR SourceMACAddr;
148 WORD_VAL Type;
149 } tWFRxPreamble;
150  
151  
152 typedef struct
153 {
154 UINT8 reserved[4];
155 } tWFTxPreamble;
156  
157  
158 /*
159 *********************************************************************************************************
160 * LOCAL GLOBAL VARIABLES
161 *********************************************************************************************************
162 */
163  
164 static BOOL g_wasDiscarded;
165  
166 static UINT8 g_encPtrRAWId[2]; /* indexed by ENC_RD_PTR_ID (0) and ENC_WT_PTR_ID (1). Values can be: */
167 /* RAW_RX_ID, RAW_TX_ID, BACKE_TCB_ADDR, RAW_INVALID_ID */
168  
169 /* keeps track of ENC read and write indexes */
170 static UINT16 g_encIndex[2]; /* index 0 stores current ENC read index, index 1 stores current ENC write index */
171  
172 static UINT16 g_rxBufferSize;
173 static UINT16 g_txPacketLength;
174 static BOOL g_txBufferFlushed;
175 static BOOL g_mgmtRxInProgress = FALSE;
176 static BOOL g_mgmtAppWaiting = FALSE;
177 #if 0
178 static UINT16 g_sizeofScratchMemory = 0;
179 #endif
180  
181 BOOL g_rxIndexSetBeyondBuffer; // debug -- remove after test
182  
183  
184 /*
185 *********************************************************************************************************
186 * LOCAL FUNCTION PROTOTYPES
187 *********************************************************************************************************
188 */
189  
190 static BOOL isMgmtTxBufAvailable(void);
191 static UINT16 MACIFService(void);
192  
193 /*****************************************************************************
194 * FUNCTION: SyncENCPtrRAWState
195 *
196 * RETURNS: None
197 *
198 * PARAMS:
199 * encPtrId -- Identifies if trying to do a read or write to ENC RAM (RAW Window).
200 * Values are ENC_RD_PTR_ID, ENC_WT_PTR_ID. g_encIndex[] must be
201 * valid before this function is called.
202 *
203 * NOTES: Any time stack code changes the index within the 'logical' Ethernet RAM
204 * this function must be called to assure the RAW driver is synced up with
205 * where the stack code thinks it is within the Ethernet RAM. This applies
206 * to reading/writing tx data, rx data, or tcb data
207 *****************************************************************************/
208 static void SyncENCPtrRAWState(UINT8 encPtrId)
209 {
210 UINT8 rawId;
211 UINT16 rawIndex;
212 UINT16 byteCount;
213 UINT32 startTickCount;
214 UINT32 maxAllowedTicks;
215  
216 EnsureWFisAwake();
217  
218 /*----------------------------------------------------*/
219 /* if encPtr[encPtrId] in the enc rx or enc tx buffer */
220 /*----------------------------------------------------*/
221 if ( g_encIndex[encPtrId] < BASE_TCB_ADDR )
222 {
223 /*--------------------------------------*/
224 /* if encPtr[encPtrId] in enc Rx buffer */
225 /*--------------------------------------*/
226 if ( g_encIndex[encPtrId] < TXSTART )
227 {
228 /* set the rawId */
229 rawId = RAW_RX_ID;
230  
231 /* Convert encPtr index to Raw Index */
232 rawIndex = g_encIndex[encPtrId] - ENC_RX_BUF_TO_RAW_RX_BUF_ADJUSTMENT;
233  
234 // encPtr[encPtrId] < (RXSTART + ENC_PREAMBLE_SIZE) is an error since we don't have
235 // the same preamble as the ENC chip
236 WF_ASSERT( g_encIndex[encPtrId] >= (RXSTART + ENC_PREAMBLE_SIZE) );
237 }
238 /*----------------------------------------*/
239 /* else encPtr[encPtrId] in enc Tx buffer */
240 /*----------------------------------------*/
241 else
242 {
243 /* if the Tx data raw window has not yet been allocated (the stack is accessing a new Tx data packet) */
244 if ( !RawWindowReady[RAW_TX_ID] )
245 {
246 /* Before we enter the while loop, get the tick timer count and save it */
247 maxAllowedTicks = TICKS_PER_SECOND / 2; /* 500 ms timeout */
248 startTickCount = (UINT32)TickGet();
249  
250 /* Retry until MRF24WB0M has drained it's prior TX pkts - multiple sockets & flows can load the MRF24W10 */
251 /* The AllocateDataTxBuffer call may not succeed immediately. */
252 while ( !AllocateDataTxBuffer(MCHP_DATA_PACKET_SIZE) )
253 {
254 /* If timed out than lock up */
255 if (TickGet() - startTickCount >= maxAllowedTicks)
256 {
257 WF_ASSERT(FALSE); /* timeout occurred */
258 }
259 } /* end while */
260 }
261  
262 /* set the rawId */
263 rawId = RAW_TX_ID;
264  
265 /* convert enc Ptr index to raw index */
266 rawIndex = g_encIndex[encPtrId] - ENC_TX_BUF_TO_RAW_TX_BUF_ADJUSTMENT;
267  
268 /* encPtr[encPtrId] < BASE_TX_ADDR is an error since we don't have the same */
269 /* pre-BASE_TX_ADDR or post tx buffer as the ENC chip */
270 WF_ASSERT((g_encIndex[encPtrId] >= BASE_TX_ADDR) && (g_encIndex[encPtrId] <= (BASE_TX_ADDR + MAX_PACKET_SIZE)));
271 }
272  
273  
274 /* Buffer should always be ready and enc pointer should always be valid. */
275 /* For the RX buffer this assert can only happen before we have received */
276 /* the first data packet. For the TX buffer this could only be the case */
277 /* after a macflush() where we couldn't re-mount a new buffer and before */
278 /* a macistxready() that successfully re-mounts a new tx buffer. */
279 WF_ASSERT(RawWindowReady[rawId]);
280  
281 /*-----------------------------------------------------------------------------*/
282 /* if the RAW buffer is ready but not mounted, or to put it another way, if */
283 /* the RAW buffer was saved, needs to be restored, and it is OK to restore it. */
284 /*-----------------------------------------------------------------------------*/
285 if (GetRawWindowState(rawId) != WF_RAW_DATA_MOUNTED)
286 {
287 /* if the buffer is not mounted then it must be restored from Mem */
288 /* a side effect is that if the scratch buffer was mounted in the raw */
289 /* then it will no longer be mounted */
290 byteCount = PopRawWindow(rawId);
291 WF_ASSERT(byteCount > 0);
292  
293 // set the buffer state
294 SetRawWindowState(rawId, WF_RAW_DATA_MOUNTED);
295 }
296 }
297 /*------------------------------------------------*/
298 /* else encPtr[encPtrId] is in the enc tcb buffer */
299 /*------------------------------------------------*/
300 else
301 {
302 /* if Rx Raw Window already mounted onto Scratch */
303 if ( GetRawWindowState(RAW_RX_ID) == WF_SCRATCH_MOUNTED )
304 {
305 rawId = RAW_RX_ID;
306 }
307 /* else if Tx Raw Window already mounted onto Scratch */
308 else if (GetRawWindowState(RAW_TX_ID) == WF_SCRATCH_MOUNTED)
309 {
310 rawId = RAW_TX_ID;
311 }
312 /* else Scratch not yet mounted, so need to decide which RAW window to use */
313 else
314 {
315 if ( (g_encPtrRAWId[1 - encPtrId]) == RAW_RX_ID )
316 {
317 /* use the Tx RAW window to write to scratch */
318 rawId = RAW_TX_ID;
319 }
320 else
321 {
322 // the other enc pointer is in use in the tx buffer raw or invalid
323 // so use the rx buffer raw to mount the scratch buffer
324  
325 // set the rawId
326 rawId = RAW_RX_ID;
327 }
328  
329 // if we currently have a buffer mounted then we need to save it
330 // need to check for both data and mgmt packets
331 if ( (GetRawWindowState(rawId) == WF_RAW_DATA_MOUNTED) || (GetRawWindowState(rawId) == WF_RAW_MGMT_MOUNTED) )
332 {
333 PushRawWindow(rawId);
334 }
335  
336 // mount the scratch window in the selected raw
337 ScratchMount(rawId);
338 }
339  
340 /* convert Enc ptr index to raw index */
341 rawIndex = g_encIndex[encPtrId] - ENC_TCB_BUF_TO_RAW_SCRATCH_BUF_ADJUSTMENT;
342 }
343  
344  
345 /* Set RAW index. If false is returned this means that index set beyond end of raw window, which */
346 /* is OK so long as no read or write access is attempted, hence the flag setting. */
347 if (RawSetIndex(rawId, rawIndex) == FALSE)
348 {
349 if ( rawId == RAW_RX_ID )
350 {
351 g_rxIndexSetBeyondBuffer = TRUE;
352 }
353 }
354 else
355 {
356 if ( rawId == RAW_RX_ID)
357 {
358 g_rxIndexSetBeyondBuffer = FALSE;
359 }
360 }
361  
362 // if we fail the set index we should...
363 // use a case statement to determine the object that is mounted (rawId==0, could be rxbuffer object or scratch object)
364 // (rawId==1, could be txbuffer or scratch object
365 // dismount the object in the appropriate manner (rxbuffer ... save operation, txbuffer save operation, scratch save operation)
366 // set the index to 0
367 // mark the RawWindowState[rawId] = WF_RAW_UNMOUNTED
368 // mark the g_encPtrRAWId[encPtrId] = RAW_INVALID_ID
369  
370  
371 // set the g_encPtrRAWId
372 g_encPtrRAWId[encPtrId] = rawId;
373  
374 // if the opposite encPtr was pointing to the raw window
375 // that was re-configured by this routine then it is
376 // no longer in sync
377 if ( g_encPtrRAWId[1-encPtrId] == g_encPtrRAWId[encPtrId] )
378 {
379 g_encPtrRAWId[1-encPtrId] = RAW_INVALID_ID;
380 }
381 }
382  
383 #if defined(STACK_CLIENT_MODE) && defined(USE_GRATUITOUS_ARP)
384 //following is the workaround algorithm for the 11Mbps broadcast bugfix
385  
386 extern void ARPResolve(IP_ADDR* IPAddr);
387 int WFArpBroadcastIntervalSec = 5; //interval in seconds, default to 5, can be changed
388 /*****************************************************************************
389 * FUNCTION: WFPeriodicGratuitousArp
390 *
391 * RETURNS: None
392 *
393 * PARAMS:
394 * None
395 *
396 * NOTES: this is a workaround algorithm for a bug appearing on some APs: they broadcasts
397 ARP Request over basic rate at 11Mpbs, that leaves our devices in dark. Here
398 we do ARP Request in the beginning for all the memebers in the subnet, then
399 periodically do Gratuitous ARP to keep ourselves alive with the AP
400 *****************************************************************************/
401 void WFPeriodicGratuitousArp(void)
402 {
403 static DWORD oldTime = 0, currTime;
404  
405 if (!MACIsLinked())
406 {
407 return;
408 }
409  
410 currTime = TickGet();
411  
412 if ( (currTime < oldTime) //wrap-around case
413 ||
414 ((currTime - oldTime) > WFArpBroadcastIntervalSec*TICK_SECOND)
415 )
416 {
417 ARPResolve(&(AppConfig.MyIPAddr));
418 oldTime = currTime;
419 }
420 }
421 #endif //defined(STACK_CLIENT_MODE) && defined(USE_GRATUITOUS_ARP)
422  
423 /*****************************************************************************
424 * FUNCTION: MACProcess
425 *
426 * RETURNS: None
427 *
428 * PARAMS:
429 * None
430 *
431 * NOTES: Called form main loop to support 802.11 operations
432 *****************************************************************************/
433 void MACProcess(void)
434 {
435  
436 // Let 802.11 processes have a chance to run
437 WFProcess();
438  
439  
440 /* SG. Deadlock avoidance code when two applications contend for the one tx pipe */
441 /* ApplicationA is a data plane application, and applicationB is a control plane application */
442 /* In this scenario, the data plane application could be the WiFi manager, and the control plane application */
443 /* a sockets application. If the sockets application keeps doing a IsUDPPutReady() and never follows with */
444 /* a UDPFlush, then the link manager will be locked out. This would be catescrophic if an AP connection */
445 /* goes down, then the link manager could never re-establish connection. Why? The link manager is a control */
446 /* plane application, which does mgmt request/confirms. */
447 /* */
448 /* Sequence of events: */
449 /* T0: ApplicationA will issue a call like UDPIsPutReady(), which results in a AllocateDataTxBuffer */
450 /* T1: ApplicationB attempts a mgmt request with IsTxMbmtReady() call. The call fails. */
451 /* T3: Stack process runs and does not deallocate the tx pipe from the data plane application. */
452 /* T4: ApplicationB attempts N+1th time, and fails. */
453 if ( g_mgmtAppWaiting )
454 {
455 if ( GetRawWindowState(RAW_TX_ID) == WF_RAW_DATA_MOUNTED )
456 {
457 /* deallocate the RAW on MRF24WB0M - return memory to pool */
458 DeallocateDataTxBuffer();
459  
460 if ( g_encPtrRAWId[ENC_RD_PTR_ID] == RAW_RX_ID )
461 {
462 g_encPtrRAWId[ENC_RD_PTR_ID] = RAW_INVALID_ID;
463 }
464  
465 if ( g_encPtrRAWId[ENC_WT_PTR_ID] == RAW_TX_ID )
466 {
467 g_encPtrRAWId[ENC_WT_PTR_ID] = RAW_INVALID_ID;
468 }
469 }
470  
471 /* This else is important in that it gives the main loop one iteration for the mgmt application to get it's timeslice */
472 /* Otherwise, a data plane task could snatch away the tx pipe again, especially if it's placed before */
473 /* the link manager in the main()'s while(1) blk. This code is functionally coupled with isRawRxMgmtInProgress() */
474 /* as it will keep the dataplane application locked out for 1 iteration, until this else is executed on N+2 iteration */
475 else
476 {
477 g_mgmtAppWaiting = FALSE;
478 }
479 }
480  
481 #if defined(STACK_CLIENT_MODE) && defined(USE_GRATUITOUS_ARP)
482 //following is the workaround algorithm for the 11Mbps broadcast bugfix
483 WFPeriodicGratuitousArp();
484 #endif
485 }
486  
487 #if 0
488 /* Not needed, removing to save g_sizeofScratchMemory storage */
489 /******************************************************************************
490 * Function: UINT16 WFGetTCBSize(void)
491 *
492 * PreCondition: None
493 *
494 * Input: None
495 *
496 * Output: Number of bytes in the TCB
497 *
498 * Side Effects: None
499 *
500 * Overview: Returns number of bytes available in TCP Control Block (TCB) so
501 * higher-layer code can determine if the number of bytes available
502 * can support the structures designated to be stored in the TCB.
503 *
504 * Note: When running with WiFi the TCB is contained in the Scratch Memory
505 * on the MRF24W.
506 *****************************************************************************/
507 UINT16 WFGetTCBSize(void)
508 {
509 return g_sizeofScratchMemory;
510 }
511 #endif
512  
513 /******************************************************************************
514 * Function: void MACInit(void)
515 *
516 * PreCondition: None
517 *
518 * Input: None
519 *
520 * Output: None
521 *
522 * Side Effects: None
523 *
524 * Overview: MACInit sets up the PIC's SPI module and all the
525 * registers in the MRF24WB0M so that normal operation can
526 * begin.
527 *
528 * Note: None
529 *****************************************************************************/
530 void MACInit(void)
531 {
532 WF_Init();
533 }
534  
535 void RawInit(void)
536 {
537 // By default (on latest B2 firmware) Scratch is mounted to RAW 1 after reset. In order to mount it on RAW0
538 // we need to first unmount it from RAW 1.
539 ScratchUnmount(RAW_TX_ID);
540  
541 // mount scratch temporarily to see how many bytes it has, then unmount it
542 // g_sizeofScratchMemory = ScratchMount(RAW_RX_ID); /* put back in if need to know size of scratch */
543 ScratchMount(RAW_RX_ID);
544 ScratchUnmount(RAW_RX_ID);
545  
546 RawWindowReady[RAW_RX_ID] = FALSE;
547  
548 g_encPtrRAWId[ENC_RD_PTR_ID] = RAW_RX_ID;
549 g_encIndex[ENC_RD_PTR_ID] = BASE_TCB_ADDR;
550  
551 // don't mount tx raw at init because it's needed for raw mgmt messages
552 RawWindowReady[RAW_TX_ID] = FALSE;
553 SetRawWindowState(RAW_TX_ID, WF_RAW_UNMOUNTED);
554  
555 g_encPtrRAWId[ENC_WT_PTR_ID] = RAW_INVALID_ID;
556 g_encIndex[ENC_WT_PTR_ID] = BASE_TX_ADDR; // set tx encode ptr (index) to start of tx buf + 4 bytes
557  
558 g_wasDiscarded = TRUE; // set state such that last rx packet was discarded
559 g_rxBufferSize = 0; // current rx buffer length (none) is 0 bytes
560 g_txPacketLength = 0; // current tx packet length (none) is 0 bytes
561 g_txBufferFlushed = TRUE; // tx buffer is flushed
562  
563 // from ENC MAC init
564 // encWrPtr is left pointing to BASE_TX_ADDR
565 // encRdPtr is not initialized... we leave it pointing to BASE_TCB_ADDR
566  
567 g_rxIndexSetBeyondBuffer = FALSE;
568 }
569  
570  
571  
572  
573 /******************************************************************************
574 * Function: BOOL MACIsLinked(void)
575 *
576 * PreCondition: None
577 *
578 * Input: None
579 *
580 * Output: TRUE: If the PHY reports that a link partner is present
581 * and the link has been up continuously since the last
582 * call to MACIsLinked()
583 * FALSE: If the PHY reports no link partner, or the link went
584 * down momentarily since the last call to MACIsLinked()
585 *
586 * Side Effects: None
587 *
588 * Overview: Returns the PHSTAT1.LLSTAT bit.
589 *
590 * Note: None
591 *****************************************************************************/
592 BOOL MACIsLinked(void)
593 {
594 return ( WFisConnected() );
595 }
596  
597  
598 /******************************************************************************
599 * Function: BOOL MACIsTxReady(void)
600 *
601 * PreCondition: None
602 *
603 * Input: None
604 *
605 * Output: TRUE: If no Ethernet transmission is in progress
606 * FALSE: If a previous transmission was started, and it has
607 * not completed yet. While FALSE, the data in the
608 * transmit buffer and the TXST/TXND pointers must not
609 * be changed.
610 *
611 * Side Effects: None
612 *
613 * Overview: Returns the ECON1.TXRTS bit
614 *
615 * Note: None
616 *****************************************************************************/
617 BOOL MACIsTxReady(void)
618 {
619 BOOL result = TRUE;
620  
621 /* Ensure the MRF24WB0M is awake (only applies if PS-Poll was enabled) */
622 EnsureWFisAwake();
623  
624  
625 /* if waiting for a management response then block data tx until */
626 /* mgmt response received */
627 if (isRawRxMgmtInProgress())
628 {
629 WFProcess(); // allow mgmt message to be received (stack can call this
630 // function in an infinite loop so need to allow WiFi state
631 // machines to run.
632 return FALSE;
633 }
634  
635 if ( !RawWindowReady[RAW_TX_ID] )
636 {
637 SetRawWindowState(RAW_TX_ID, WF_RAW_UNMOUNTED);
638  
639 if ( g_encPtrRAWId[ENC_RD_PTR_ID] == RAW_TX_ID )
640 {
641 g_encPtrRAWId[ENC_RD_PTR_ID] = RAW_INVALID_ID;
642 }
643  
644 if ( g_encPtrRAWId[ENC_WT_PTR_ID] == RAW_TX_ID )
645 {
646 g_encPtrRAWId[ENC_WT_PTR_ID] = RAW_INVALID_ID;
647 }
648  
649 // create the new tx buffer
650 if (!AllocateDataTxBuffer(MCHP_DATA_PACKET_SIZE) )
651 {
652 result = FALSE;
653 }
654 }
655  
656 return result;
657 }
658  
659 // determines if a RAW Tx buf is ready for a management msg, and if so, creates the RAW tx buffer.
660 // Returns TRUE if successful, else FALSE.
661 BOOL WFisTxMgmtReady(void)
662 {
663 BOOL res = TRUE;
664  
665 if (isMgmtTxBufAvailable())
666 {
667 // create and mount tx buffer to hold RAW Mgmt packet
668 if (AllocateMgmtTxBuffer(WF_MAX_TX_MGMT_MSG_SIZE))
669 {
670 res = TRUE;
671  
672 /* Bug. This flag must be set otherwise the data path does not know */
673 /* that the tx pipe has been mounted for mgmt operation. SG */
674 SetRawRxMgmtInProgress(TRUE);
675 }
676 else
677 {
678 res = FALSE;
679 }
680 }
681 // else Tx RAW not available for Mgmt packet
682 else
683 {
684 res = FALSE;
685  
686 /* See comment in MACProcess */
687 g_mgmtAppWaiting = TRUE;
688 }
689  
690 return res;
691 }
692  
693  
694 void WFFreeMgmtTx(void)
695 {
696 // This flag needs to clear so data path can proceed.
697 SetRawRxMgmtInProgress(FALSE);
698 }
699  
700 static BOOL isMgmtTxBufAvailable(void)
701 {
702 // if the Tx RAW buf is not being used for a data packet or scratch, then it
703 // is available for a Mgmt packet.
704 if ((RawWindowReady[RAW_TX_ID] == FALSE)
705 &&
706 ((GetRawWindowState(RAW_TX_ID) == WF_RAW_UNMOUNTED) || (GetRawWindowState(RAW_TX_ID) == WF_SCRATCH_MOUNTED)))
707 {
708 SetRawWindowState(RAW_TX_ID, WF_RAW_UNMOUNTED);
709 return TRUE;
710 }
711 else
712 {
713 return FALSE;
714 }
715  
716  
717 }
718  
719 BOOL SendRAWManagementFrame(UINT16 bufLen)
720 {
721 /* Instruct WF chip to transmit the packet data in the raw window */
722 RawSendTxBuffer(bufLen);
723  
724 /* let tx buffer be reused (for either data or management tx) */
725 WFFreeMgmtTx();
726  
727 return TRUE;
728 }
729  
730  
731  
732  
733 // returns TRUE if able to acquire the RAW Rx window for the purpose
734 // of processing a management receive message
735  
736 BOOL RawGetMgmtRxBuffer(UINT16 *p_numBytes)
737 {
738 BOOL res = TRUE;
739 // UINT16 numBytes;
740 *p_numBytes = 0;
741  
742 // if Raw Rx is not currently mounted, or the Scratch is mounted
743 if (GetRawWindowState(RAW_RX_ID) == WF_RAW_DATA_MOUNTED)
744 {
745 // save whatever was mounted to Raw Rx
746 PushRawWindow(RAW_RX_ID);
747 }
748  
749 // mount the mgmt pool rx data, returns number of bytes in mgmt msg. Index
750 // defaults to 0.
751 *p_numBytes = RawMountRxBuffer();
752  
753 /* Should never receive a mgmt msg with 0 bytes */
754 WF_ASSERT(*p_numBytes > 0);
755  
756 // set flag so we do not try to mount an incoming data packet until after the rx Mgmt msg
757 // has been handled.
758 SetRawRxMgmtInProgress(TRUE);
759  
760  
761 return res;
762 }
763  
764  
765 void SetRawRxMgmtInProgress(BOOL action)
766 {
767 if (action == FALSE)
768 {
769 // RawWindowReady[RAW_RX_ID] = TRUE;
770 SetRawWindowState(RAW_RX_ID, WF_RAW_UNMOUNTED);
771 }
772  
773 g_mgmtRxInProgress = action;
774 }
775  
776  
777  
778 BOOL isRawRxMgmtInProgress(void)
779 {
780 return g_mgmtRxInProgress; // RawMgtmAppWaiting flag not needed and was causing problems
781 }
782  
783  
784 /******************************************************************************
785 * Function: void MACDiscardRx(void)
786 *
787 * PreCondition: None
788 *
789 * Input: None
790 *
791 * Output: None
792 *
793 * Side Effects: None
794 *
795 * Overview: Marks the last received packet (obtained using
796 * MACGetHeader())as being processed and frees the buffer
797 * memory associated with it
798 *
799 * Note: It is safe to call this function multiple times between
800 * MACGetHeader() calls. Extra packets won't be thrown away
801 * until MACGetHeader() makes it available.
802 *****************************************************************************/
803 void MACDiscardRx(void)
804 {
805 g_wasDiscarded = TRUE;
806 }
807  
808  
809 /******************************************************************************
810 * Function: WORD MACGetFreeRxSize(void)
811 *
812 * PreCondition: None
813 *
814 * Input: None
815 *
816 * Output: A WORD estimate of how much RX buffer space is free at
817 * the present time.
818 *
819 * Side Effects: None
820 *
821 * Overview: None
822 *
823 * Note: None
824 *****************************************************************************/
825 WORD MACGetFreeRxSize(void)
826 {
827 WORD size;
828  
829 if ( g_wasDiscarded )
830 {
831 size = RXSIZE - 1;
832 }
833 else
834 {
835 if ( (RXSTOP - RXSTART) > g_rxBufferSize )
836 {
837 size = (RXSTOP - RXSTART) - g_rxBufferSize;
838 }
839 else
840 {
841 size = 0;
842 }
843 }
844  
845 return size;
846 }
847  
848 /*****************************************************************************
849 * FUNCTION: MACIFService
850 *
851 *
852 * RETURNS: Number of bytes in the Data Rx packet if one is received, else 0.
853 *
854 * PARAMS: None
855 *
856 * NOTES: Called by MACGetHeader() to see if any data packets have been received.
857 * If the MRF24WB0M has received a data packet and the data packet is not
858 * a management data packet, then this function returns the number of
859 * bytes in the data packet. Otherwise it returns 0.
860 *****************************************************************************/
861 static UINT16 MACIFService(void)
862 {
863 UINT16 byteCount = 0; /* num bytes returned */
864 tRxPreamble wfPreamble;
865  
866 // if no rx data packet to process or not yet finished with mgmt rx processing
867 if (!g_HostRAWDataPacketReceived)
868 {
869 return byteCount;
870 }
871  
872 /* if made it here then External interrupt has signalled a data packet has been received */
873  
874  
875 g_HostRAWDataPacketReceived = FALSE; /* clear flag for next data packet */
876  
877 // made it here if RAW rx data packet to handle, so make sure MRF24WB0M is awake
878 EnsureWFisAwake();
879  
880 /* Mount Read FIFO to RAW Rx window. Allows use of RAW engine to read rx data packet. */
881 /* Function call returns number of bytes in the data packet. */
882 byteCount = RawMountRxBuffer();
883 WF_ASSERT(byteCount > 0); /* byte count should never be 0 */
884  
885 // now that buffer mounted it is safe to reenable interrupts
886 WF_EintEnable();
887  
888 RawGetByte(RAW_RX_ID, (UINT8*)&wfPreamble, sizeof(tRxPreamble));
889 WF_ASSERT(wfPreamble.type == WF_DATA_RX_INDICATE_TYPE);
890  
891 return byteCount;
892 }
893  
894  
895 /******************************************************************************
896 * Function: BOOL MACGetHeader(MAC_ADDR *remote, BYTE* type)
897 *
898 * PreCondition: None
899 *
900 * Input: *remote: Location to store the Source MAC address of the
901 * received frame.
902 * *type: Location of a BYTE to store the constant
903 * MAC_UNKNOWN, ETHER_IP, or ETHER_ARP, representing
904 * the contents of the Ethernet type field.
905 *
906 * Output: TRUE: If a packet was waiting in the RX buffer. The
907 * remote, and type values are updated.
908 * FALSE: If a packet was not pending. remote and type are
909 * not changed.
910 *
911 * Side Effects: Last packet is discarded if MACDiscardRx() hasn't already
912 * been called.
913 *
914 * Overview: None
915 *
916 * Note: None
917 *****************************************************************************/
918 BOOL MACGetHeader(MAC_ADDR *remote, BYTE* type)
919 {
920 UINT16 len;
921 tWFRxPreamble header;
922  
923 g_rxIndexSetBeyondBuffer = FALSE;
924  
925 /* if we currently have a rx buffer mounted then we need to save it */
926 if ( GetRawWindowState(RAW_RX_ID) == WF_RAW_DATA_MOUNTED )
927 {
928 EnsureWFisAwake();
929 /* save state of Rx RAW window */
930 PushRawWindow(RAW_RX_ID);
931 }
932  
933 /* RAW 0 is now unmounted (and available) */
934 SetRawWindowState(RAW_RX_ID, WF_RAW_UNMOUNTED);
935  
936 if ( g_encPtrRAWId[ENC_RD_PTR_ID] == RAW_RX_ID )
937 {
938 g_encPtrRAWId[ENC_RD_PTR_ID] = RAW_INVALID_ID;
939 }
940  
941 if ( g_encPtrRAWId[ENC_WT_PTR_ID] == RAW_RX_ID )
942 {
943 g_encPtrRAWId[ENC_WT_PTR_ID] = RAW_INVALID_ID;
944 }
945  
946 len = MACIFService();
947 if ( len == 0 )
948 {
949 return FALSE;
950 }
951  
952 /* read preamble header */
953 RawRead(RAW_RX_ID, ENC_PREAMBLE_OFFSET, WF_RX_PREAMBLE_SIZE, (UINT8 *)&header);
954  
955 /* as a sanity check verify that the expected bytes contain the SNAP header */
956 if (!(header.snap[0] == SNAP_VAL &&
957 header.snap[1] == SNAP_VAL &&
958 header.snap[2] == SNAP_CTRL_VAL &&
959 header.snap[3] == SNAP_TYPE_VAL &&
960 header.snap[4] == SNAP_TYPE_VAL &&
961 header.snap[5] == SNAP_TYPE_VAL) )
962 {
963 /* if a vendor proprietary packet, throw away */
964 DeallocateDataRxBuffer();
965 return FALSE;
966 }
967  
968 // Make absolutely certain that any previous packet was discarded
969 g_wasDiscarded = TRUE;
970  
971 /* we can flush any saved RAW state now by saving and restoring the current rx buffer. */
972 PushRawWindow(RAW_RX_ID);
973 PopRawWindow(RAW_RX_ID);
974  
975 // set RAW pointer to 802.11 payload
976 RawSetIndex(RAW_RX_ID, (ENC_PREAMBLE_OFFSET + WF_RX_PREAMBLE_SIZE));
977  
978 g_rxBufferSize = len;
979 ///// RawWindowReady[RAW_RX_ID] = TRUE;
980 ///// SetRawWindowState(RAW_RX_ID, WF_RAW_DATA_MOUNTED);
981 g_encPtrRAWId[ENC_RD_PTR_ID] = RAW_RX_ID;
982 g_encIndex[ENC_RD_PTR_ID] = RXSTART + sizeof(ENC_PREAMBLE);
983  
984 // The EtherType field, like most items transmitted on the Ethernet medium
985 // are in big endian.
986 header.Type.Val = swaps(header.Type.Val);
987  
988 // Return the Ethernet frame's Source MAC address field to the caller
989 // This parameter is useful for replying to requests without requiring an
990 // ARP cycle.
991 memcpy((void*)remote->v, (void*)header.SourceMACAddr.v, sizeof(*remote));
992  
993 // Return a simplified version of the EtherType field to the caller
994 *type = MAC_UNKNOWN;
995 if( (header.Type.v[1] == 0x08u) &&
996 ((header.Type.v[0] == ETHER_IP) || (header.Type.v[0] == ETHER_ARP)) )
997 {
998 *type = header.Type.v[0];
999 }
1000  
1001 // Mark this packet as discardable
1002 g_wasDiscarded = FALSE;
1003  
1004 return TRUE;
1005 }
1006  
1007 /******************************************************************************
1008 * Function: void MACPutHeader(MAC_ADDR *remote, BYTE type, WORD dataLen)
1009 *
1010 * PreCondition: MACIsTxReady() must return TRUE.
1011 *
1012 * Input: *remote: Pointer to memory which contains the destination
1013 * MAC address (6 bytes)
1014 * type: The constant ETHER_ARP or ETHER_IP, defining which
1015 * value to write into the Ethernet header's type field.
1016 * dataLen: Length of the Ethernet data payload
1017 *
1018 * Output: None
1019 *
1020 * Side Effects: None
1021 *
1022 * Overview: None
1023 *
1024 * Note: Because of the dataLen parameter, it is probably
1025 * advantagous to call this function immediately before
1026 * transmitting a packet rather than initially when the
1027 * packet is first created. The order in which the packet
1028 * is constructed (header first or data first) is not
1029 * important.
1030 *****************************************************************************/
1031 void MACPutHeader(MAC_ADDR *remote, BYTE type, WORD dataLen)
1032 {
1033 UINT8 buf[14];
1034 g_txBufferFlushed = FALSE;
1035 g_txPacketLength = dataLen + (WORD)sizeof(ETHER_HEADER) + WF_TX_PREAMBLE_SIZE;
1036  
1037 // Set the SPI write pointer to the beginning of the transmit buffer (post WF_TX_PREAMBLE_SIZE)
1038 g_encIndex[ENC_WT_PTR_ID] = TXSTART + WF_TX_PREAMBLE_SIZE;
1039 SyncENCPtrRAWState(ENC_WT_PTR_ID);
1040  
1041 /* write the Ethernet destination address to buffer (6 bytes) */
1042 memcpy(&buf[0], (void *)remote, sizeof(*remote));
1043 /* write snap header to buffer (6 bytes) */
1044 buf[6] = SNAP_VAL;
1045 buf[7] = SNAP_VAL;
1046 buf[8] = SNAP_CTRL_VAL;
1047 buf[9] = SNAP_TYPE_VAL;
1048 buf[10] = SNAP_TYPE_VAL;
1049 buf[11] = SNAP_TYPE_VAL;
1050 /* Write the appropriate Ethernet Type WORD for the protocol being used */
1051 buf[12] = 0x08;
1052 buf[13] = (type == MAC_IP) ? ETHER_IP : ETHER_ARP;
1053  
1054 /* write buffer to RAW window */
1055 MACPutArray((BYTE *)buf, sizeof(buf));
1056 }
1057  
1058  
1059  
1060 /******************************************************************************
1061 * Function: void MACFlush(void)
1062 *
1063 * PreCondition: A packet has been created by calling MACPut() and
1064 * MACPutHeader().
1065 *
1066 * Input: None
1067 *
1068 * Output: None
1069 *
1070 * Side Effects: None
1071 *
1072 * Overview: MACFlush causes the current TX packet to be sent out on
1073 * the Ethernet medium. The hardware MAC will take control
1074 * and handle CRC generation, collision retransmission and
1075 * other details.
1076 *
1077 * Note: After transmission completes (MACIsTxReady() returns TRUE),
1078 * the packet can be modified and transmitted again by calling
1079 * MACFlush() again. Until MACPutHeader() or MACPut() is
1080 * called (in the TX data area), the data in the TX buffer
1081 * will not be corrupted.
1082 *****************************************************************************/
1083 void MACFlush(void)
1084 {
1085 /* this function should not be called if no tx buffer is ready to transmit */
1086 WF_ASSERT(RawWindowReady[RAW_TX_ID]);
1087  
1088 /* this function should not be called after the current tx buffer has been transmitted */
1089 WF_ASSERT(!g_txBufferFlushed);
1090  
1091 g_txBufferFlushed = TRUE;
1092  
1093 /* If the RAW engine is not currently mounted */
1094 if ( GetRawWindowState(RAW_TX_ID) != WF_RAW_DATA_MOUNTED )
1095 {
1096 /* then it must have been saved, so pop it */
1097 PopRawWindow(RAW_TX_ID);
1098 }
1099  
1100 // at this point the txbuffer should be mounted and ready to go
1101  
1102 /* can't send a tx packet of 0 bytes! */
1103 WF_ASSERT(g_txPacketLength != 0);
1104  
1105 SendRAWDataFrame(g_txPacketLength);
1106  
1107 // make sure to de-sync any affected pointers
1108 if ( g_encPtrRAWId[ENC_RD_PTR_ID] == RAW_TX_ID )
1109 {
1110 g_encPtrRAWId[ENC_RD_PTR_ID] = RAW_INVALID_ID;
1111 }
1112  
1113 if ( g_encPtrRAWId[ENC_WT_PTR_ID] == RAW_TX_ID )
1114 {
1115 g_encPtrRAWId[ENC_WT_PTR_ID] = RAW_INVALID_ID;
1116 }
1117 }
1118  
1119  
1120 /******************************************************************************
1121 * Function: void MACSetReadPtrInRx(WORD offset)
1122 *
1123 * PreCondition: A packet has been obtained by calling MACGetHeader() and
1124 * getting a TRUE result.
1125 *
1126 * Input: offset: WORD specifying how many bytes beyond the Ethernet
1127 * header's type field to relocate the SPI read
1128 * pointer.
1129 *
1130 * Output: None
1131 *
1132 * Side Effects: None
1133 *
1134 * Overview: SPI read pointer are updated. All calls to
1135 * MACGet() and MACGetArray() will use these new values.
1136 *
1137 * Note: RXSTOP must be statically defined as being > RXSTART for
1138 * this function to work correctly. In other words, do not
1139 * define an RX buffer which spans the 0x1FFF->0x0000 memory
1140 * boundary.
1141 *****************************************************************************/
1142 void MACSetReadPtrInRx(WORD offset)
1143 {
1144 g_encIndex[ENC_RD_PTR_ID] = RXSTART + sizeof(ENC_PREAMBLE) + offset;
1145 SyncENCPtrRAWState(ENC_RD_PTR_ID);
1146 }
1147  
1148  
1149 /******************************************************************************
1150 * Function: WORD MACSetWritePtr(WORD Address)
1151 *
1152 * PreCondition: None
1153 *
1154 * Input: Address: Address to seek to
1155 *
1156 * Output: WORD: Old EWRPT location
1157 *
1158 * Side Effects: None
1159 *
1160 * Overview: SPI write pointer is updated. All calls to
1161 * MACPut() and MACPutArray() will use this new value.
1162 *
1163 * Note: None
1164 *****************************************************************************/
1165 PTR_BASE MACSetWritePtr(PTR_BASE address)
1166 {
1167 PTR_BASE oldVal;
1168  
1169 oldVal = g_encIndex[ENC_WT_PTR_ID];
1170  
1171 g_encIndex[ENC_WT_PTR_ID] = address;
1172  
1173 SyncENCPtrRAWState(ENC_WT_PTR_ID);
1174  
1175 return oldVal;
1176 }
1177  
1178 /******************************************************************************
1179 * Function: WORD MACSetReadPtr(WORD Address)
1180 *
1181 * PreCondition: None
1182 *
1183 * Input: Address: Address to seek to
1184 *
1185 * Output: WORD: Old ERDPT value
1186 *
1187 * Side Effects: None
1188 *
1189 * Overview: SPI write pointer is updated. All calls to
1190 * MACPut() and MACPutArray() will use this new value.
1191 *
1192 * Note: None
1193 *****************************************************************************/
1194 PTR_BASE MACSetReadPtr(PTR_BASE address)
1195 {
1196 PTR_BASE oldVal;
1197  
1198 oldVal = g_encIndex[ENC_RD_PTR_ID];
1199  
1200 g_encIndex[ENC_RD_PTR_ID] = address;
1201 SyncENCPtrRAWState(ENC_RD_PTR_ID);
1202  
1203 return oldVal;
1204 }
1205  
1206  
1207 /******************************************************************************
1208 * Function: WORD MACCalcRxChecksum(WORD offset, WORD len)
1209 *
1210 * PreCondition: None
1211 *
1212 * Input: offset - Number of bytes beyond the beginning of the
1213 * Ethernet data (first byte after the type field)
1214 * where the checksum should begin
1215 * len - Total number of bytes to include in the checksum
1216 *
1217 * Output: 16-bit checksum as defined by RFC 793.
1218 *
1219 * Side Effects: None
1220 *
1221 * Overview: This function performs a checksum calculation in the MAC
1222 * buffer itself
1223 *
1224 * Note: None
1225 *****************************************************************************/
1226 WORD MACCalcRxChecksum(WORD offset, WORD len)
1227 {
1228 WORD temp;
1229 UINT16 rdSave;
1230  
1231 // Add the offset requested by firmware plus the Ethernet header
1232 temp = RXSTART + sizeof(ENC_PREAMBLE) + offset;
1233  
1234 rdSave = g_encIndex[ENC_RD_PTR_ID];
1235  
1236 g_encIndex[ENC_RD_PTR_ID] = temp;
1237 SyncENCPtrRAWState(ENC_RD_PTR_ID);
1238  
1239 temp = CalcIPBufferChecksum(len);
1240  
1241 g_encIndex[ENC_RD_PTR_ID] = rdSave;
1242 SyncENCPtrRAWState(ENC_RD_PTR_ID);
1243  
1244 return temp;
1245 }
1246  
1247  
1248 /******************************************************************************
1249 * Function: void MACMemCopyAsync(WORD destAddr, WORD sourceAddr, WORD len)
1250 *
1251 * PreCondition: SPI bus must be initialized (done in MACInit()).
1252 *
1253 * Input: destAddr: Destination address in the Ethernet memory to
1254 * copy to. If the MSb is set, the current EWRPT
1255 * value will be used instead.
1256 * sourceAddr: Source address to read from. If the MSb is
1257 * set, the current ERDPT value will be used
1258 * instead.
1259 * len: Number of bytes to copy
1260 *
1261 * Output: Byte read from the MRF24W's RAM
1262 *
1263 * Side Effects: None
1264 *
1265 * Overview: Bytes are asynchrnously transfered within the buffer. Call
1266 * MACIsMemCopyDone() to see when the transfer is complete.
1267 *
1268 * Note: If a prior transfer is already in progress prior to
1269 * calling this function, this function will block until it
1270 * can start this transfer.
1271 *
1272 * If a negative value is used for the sourceAddr or destAddr
1273 * parameters, then that pointer will get updated with the
1274 * next address after the read or write.
1275 *****************************************************************************/
1276 void MACMemCopyAsync(PTR_BASE destAddr, PTR_BASE sourceAddr, WORD len)
1277 {
1278 UINT16 readSave = 0, writeSave = 0;
1279 BOOL updateWritePointer;
1280 BOOL updateReadPointer;
1281 UINT8 rawScratchId = 0xff; /* garbage value to avoid compiler warning */
1282 UINT8 copyBuf[8];
1283 UINT16 writeIndex, readIndex;
1284 UINT16 bytesLeft;
1285 UINT16 origRawIndex;
1286  
1287 if( ((WORD_VAL*)&destAddr)->bits.b15 )
1288 {
1289 updateWritePointer = TRUE;
1290 destAddr = g_encIndex[ENC_WT_PTR_ID];
1291 if ( g_encPtrRAWId[ENC_WT_PTR_ID] == RAW_INVALID_ID )
1292 {
1293 SyncENCPtrRAWState(ENC_WT_PTR_ID);
1294 }
1295 }
1296 else
1297 {
1298 updateWritePointer = FALSE;
1299 writeSave = g_encIndex[ENC_WT_PTR_ID];
1300 g_encIndex[ENC_WT_PTR_ID] = destAddr;
1301 SyncENCPtrRAWState(ENC_WT_PTR_ID);
1302 }
1303  
1304 if( ((WORD_VAL*)&sourceAddr)->bits.b15 )
1305 {
1306 updateReadPointer = TRUE;
1307 sourceAddr = g_encIndex[ENC_RD_PTR_ID];
1308 if ( g_encPtrRAWId[ENC_RD_PTR_ID] == RAW_INVALID_ID )
1309 {
1310 SyncENCPtrRAWState(ENC_RD_PTR_ID);
1311 }
1312 }
1313 else
1314 {
1315 updateReadPointer = FALSE;
1316 readSave = g_encIndex[ENC_RD_PTR_ID];
1317 g_encIndex[ENC_RD_PTR_ID] = sourceAddr;
1318 SyncENCPtrRAWState(ENC_RD_PTR_ID);
1319 }
1320  
1321 // if copying bytes from TCB to TCB
1322 // This is a special case because we cannot do a RAW copy within the same RAW window
1323 // but we can easily copy Scratch data from one section of Scratch to another section of Scratch.
1324 if ( (len > 0u) && (destAddr >= BASE_TCB_ADDR) && (sourceAddr >= BASE_TCB_ADDR) )
1325 {
1326 bytesLeft = len;
1327  
1328 // if Raw Rx window mounted to scratch
1329 if (GetRawWindowState(RAW_RX_ID) == WF_SCRATCH_MOUNTED)
1330 {
1331 rawScratchId = RAW_RX_ID;
1332 }
1333 // else if Raw Tx window mounted to scratch
1334 else if (GetRawWindowState(RAW_TX_ID) == WF_SCRATCH_MOUNTED)
1335 {
1336 rawScratchId = RAW_TX_ID;
1337 }
1338 else
1339 {
1340 WF_ASSERT(FALSE); /* this should never happen (that can't mount scratch on either RAW window) */
1341 }
1342  
1343 // save the current RAW index in this scratch window
1344 origRawIndex = RawGetIndex(rawScratchId);
1345  
1346 // If TCB src block does not overlap TCB dest block, or if destAddr > sourceAddr.
1347 // We can do a forward copy.
1348 if ( ((sourceAddr + len) <= destAddr) || // end of source before dest (no overlap)
1349 ((destAddr + len) <= sourceAddr) || // end of dest before source (no overlap)
1350 (destAddr < sourceAddr) // dest before source (overlap)
1351 )
1352 {
1353  
1354 // map read index from TCB address to Scratch Index
1355 readIndex = sourceAddr - ENC_TCB_BUF_TO_RAW_SCRATCH_BUF_ADJUSTMENT;
1356 writeIndex = destAddr - ENC_TCB_BUF_TO_RAW_SCRATCH_BUF_ADJUSTMENT;
1357  
1358 while (bytesLeft > 0)
1359 {
1360 // if a full copyBuf worth of bytes to copy
1361 if (bytesLeft >= sizeof(copyBuf))
1362 {
1363 RawRead(rawScratchId, readIndex, sizeof(copyBuf), copyBuf);
1364 RawWrite(rawScratchId, writeIndex, sizeof(copyBuf), copyBuf);
1365  
1366 // index to next block in source and dest
1367 readIndex += sizeof(copyBuf);
1368 writeIndex += sizeof(copyBuf);
1369 bytesLeft -= sizeof(copyBuf);
1370 }
1371 // else less than a full copyBuf left to copy
1372 else
1373 {
1374 if (bytesLeft > 0)
1375 {
1376 RawRead(rawScratchId, readIndex, bytesLeft, copyBuf);
1377 RawWrite(rawScratchId, writeIndex, bytesLeft, copyBuf);
1378 bytesLeft = 0;
1379 }
1380 }
1381 }
1382 } // end while
1383 // else start of TCB dest block within TCB src block --> destAddr > sourcAddr
1384 // Do a backward copy.
1385 else if (destAddr > sourceAddr)
1386 {
1387 // map read index from TCB address to Scratch Index
1388 readIndex = sourceAddr - ENC_TCB_BUF_TO_RAW_SCRATCH_BUF_ADJUSTMENT + len - 1;
1389 writeIndex = destAddr - ENC_TCB_BUF_TO_RAW_SCRATCH_BUF_ADJUSTMENT + len - 1;
1390  
1391 while (bytesLeft > 0)
1392 {
1393 // if a full copyBuf worth of bytes to copy
1394 if (bytesLeft >= sizeof(copyBuf))
1395 {
1396 RawRead(rawScratchId, readIndex - sizeof(copyBuf) + 1, sizeof(copyBuf), copyBuf);
1397 RawWrite(rawScratchId, writeIndex - sizeof(copyBuf) + 1, sizeof(copyBuf), copyBuf);
1398  
1399 // index to next block in source and dest
1400 readIndex -= sizeof(copyBuf);
1401 writeIndex -= sizeof(copyBuf);
1402 bytesLeft -= sizeof(copyBuf);
1403 }
1404 // else less than a full copyBuf left to copy
1405 else
1406 {
1407 if (bytesLeft > 0)
1408 {
1409 RawRead(rawScratchId, readIndex - bytesLeft + 1, bytesLeft - 1, copyBuf);
1410 RawWrite(rawScratchId, writeIndex - bytesLeft + 1, bytesLeft - 1, copyBuf);
1411 bytesLeft = 0;
1412 }
1413 }
1414 } // end while
1415 }
1416 // restore raw index to where it was when this function was called
1417 RawSetIndex(rawScratchId, origRawIndex);
1418  
1419 }
1420 // else if not copying from TCB to TCB and there is at least one byte to copy
1421 else if ( len > 0)
1422 {
1423 // Check if app is trying to copy data within same RAW window (can't do that)
1424 if ( (g_encPtrRAWId[ENC_RD_PTR_ID] == RAW_INVALID_ID) ||
1425 (g_encPtrRAWId[ENC_WT_PTR_ID] == RAW_INVALID_ID) )
1426 {
1427 WF_ASSERT(FALSE);
1428 }
1429 RawToRawCopy(g_encPtrRAWId[ENC_WT_PTR_ID], len);
1430 }
1431  
1432 if ( !updateReadPointer )
1433 {
1434 g_encIndex[ENC_RD_PTR_ID] = readSave;
1435 SyncENCPtrRAWState(ENC_RD_PTR_ID);
1436 }
1437  
1438 if ( !updateWritePointer )
1439 {
1440 g_encIndex[ENC_WT_PTR_ID] = writeSave;
1441 SyncENCPtrRAWState(ENC_WT_PTR_ID);
1442 }
1443 } /* end MACMemCopyAsync */
1444  
1445  
1446 BOOL MACIsMemCopyDone(void)
1447 {
1448 return TRUE;
1449 }
1450  
1451  
1452 /******************************************************************************
1453 * Function: BYTE MACGet()
1454 *
1455 * PreCondition: SPI bus must be initialized (done in MACInit()).
1456 * ERDPT must point to the place to read from.
1457 *
1458 * Input: None
1459 *
1460 * Output: Byte read from the MRF24W's RAM
1461 *
1462 * Side Effects: None
1463 *
1464 * Overview: MACGet returns the byte pointed to by ERDPT and
1465 * increments ERDPT so MACGet() can be called again. The
1466 * increment will follow the receive buffer wrapping boundary.
1467 *
1468 * Note: None
1469 *****************************************************************************/
1470 BYTE MACGet()
1471 {
1472 BYTE result;
1473  
1474 if ( g_encPtrRAWId[ENC_RD_PTR_ID] == RAW_INVALID_ID )
1475 {
1476 SyncENCPtrRAWState(ENC_RD_PTR_ID);
1477 }
1478  
1479 RawGetByte(g_encPtrRAWId[ENC_RD_PTR_ID], &result, 1);
1480  
1481 g_encIndex[ENC_RD_PTR_ID] += 1;
1482  
1483 return result;
1484 }//end MACGet
1485  
1486  
1487 /******************************************************************************
1488 * Function: WORD MACGetArray(BYTE *val, WORD len)
1489 *
1490 * PreCondition: SPI bus must be initialized (done in MACInit()).
1491 * ERDPT must point to the place to read from.
1492 *
1493 * Input: *val: Pointer to storage location
1494 * len: Number of bytes to read from the data buffer.
1495 *
1496 * Output: Byte(s) of data read from the data buffer.
1497 *
1498 * Side Effects: None
1499 *
1500 * Overview: Burst reads several sequential bytes from the data buffer
1501 * and places them into local memory. With SPI burst support,
1502 * it performs much faster than multiple MACGet() calls.
1503 * ERDPT is incremented after each byte, following the same
1504 * rules as MACGet().
1505 *
1506 * Note: None
1507 *****************************************************************************/
1508 WORD MACGetArray(BYTE *val, WORD len)
1509 {
1510 WORD i = 0;
1511 UINT8 byte;
1512  
1513 if ( g_encPtrRAWId[ENC_RD_PTR_ID] == RAW_INVALID_ID )
1514 {
1515 SyncENCPtrRAWState(ENC_RD_PTR_ID);
1516 }
1517  
1518 if ( val )
1519 {
1520 RawGetByte(g_encPtrRAWId[ENC_RD_PTR_ID], val, len);
1521 }
1522 else
1523 {
1524 // Read the data
1525 while(i<len)
1526 {
1527 RawGetByte(g_encPtrRAWId[ENC_RD_PTR_ID], &byte, 1);
1528 i++;
1529 }
1530 }
1531 g_encIndex[ENC_RD_PTR_ID] += len;
1532  
1533 return len;
1534 }//end MACGetArray
1535  
1536  
1537 /******************************************************************************
1538 * Function: void MACPut(BYTE val)
1539 *
1540 * PreCondition: SPI bus must be initialized (done in MACInit()).
1541 * EWRPT must point to the location to begin writing.
1542 *
1543 * Input: Byte to write into the MRF24WB0M buffer memory
1544 *
1545 * Output: None
1546 *
1547 * Side Effects: None
1548 *
1549 * Overview: MACPut outputs the Write Buffer Memory opcode/constant
1550 * (8 bits) and data to write (8 bits) over the SPI.
1551 * EWRPT is incremented after the write.
1552 *
1553 * Note: None
1554 *****************************************************************************/
1555 void MACPut(BYTE val)
1556 {
1557 UINT8 byte = val;
1558  
1559 if ( g_encPtrRAWId[ENC_WT_PTR_ID] == RAW_INVALID_ID )
1560 {
1561 SyncENCPtrRAWState(ENC_WT_PTR_ID);
1562 }
1563  
1564 RawSetByte(g_encPtrRAWId[ENC_WT_PTR_ID], &byte, 1);
1565  
1566 g_encIndex[ENC_WT_PTR_ID] += 1;
1567 }//end MACPut
1568  
1569  
1570 /******************************************************************************
1571 * Function: void MACPutArray(BYTE *val, WORD len)
1572 *
1573 * PreCondition: SPI bus must be initialized (done in MACInit()).
1574 * EWRPT must point to the location to begin writing.
1575 *
1576 * Input: *val: Pointer to source of bytes to copy.
1577 * len: Number of bytes to write to the data buffer.
1578 *
1579 * Output: None
1580 *
1581 * Side Effects: None
1582 *
1583 * Overview: MACPutArray writes several sequential bytes to the
1584 * MRF24WB0M RAM. It performs faster than multiple MACPut()
1585 * calls. EWRPT is incremented by len.
1586 *
1587 * Note: None
1588 *****************************************************************************/
1589 void MACPutArray(BYTE *val, WORD len)
1590 {
1591 if ( g_encPtrRAWId[ENC_WT_PTR_ID] == RAW_INVALID_ID )
1592 {
1593 SyncENCPtrRAWState(ENC_WT_PTR_ID);
1594 }
1595  
1596 RawSetByte(g_encPtrRAWId[ENC_WT_PTR_ID], val, len);
1597  
1598 g_encIndex[ENC_WT_PTR_ID] += len;
1599 }//end MACPutArray
1600  
1601  
1602 /******************************************************************************
1603 * Function: void MACPutROMArray(ROM BYTE *val, WORD len)
1604 *
1605 * PreCondition: SPI bus must be initialized (done in MACInit()).
1606 * EWRPT must point to the location to begin writing.
1607 *
1608 * Input: *val: Pointer to source of bytes to copy.
1609 * len: Number of bytes to write to the data buffer.
1610 *
1611 * Output: None
1612 *
1613 * Side Effects: None
1614 *
1615 * Overview: MACPutArray writes several sequential bytes to the
1616 * MRF24WB0M RAM. It performs faster than multiple MACPut()
1617 * calls. EWRPT is incremented by len.
1618 *
1619 * Note: None
1620 *****************************************************************************/
1621 #if defined(__18CXX)
1622 void MACPutROMArray(ROM BYTE *val, WORD len)
1623 {
1624 if ( g_encPtrRAWId[ENC_WT_PTR_ID] == RAW_INVALID_ID )
1625 {
1626 SyncENCPtrRAWState(ENC_WT_PTR_ID);
1627 }
1628  
1629 RawSetByteROM(g_encPtrRAWId[ENC_WT_PTR_ID], val, len);
1630  
1631 g_encIndex[ENC_WT_PTR_ID] += len;
1632 }//end MACPutROMArray
1633 #endif
1634  
1635  
1636 /******************************************************************************
1637 * Function: void MACPowerDown(void)
1638 *
1639 * PreCondition: SPI bus must be initialized (done in MACInit()).
1640 *
1641 * Input: None
1642 *
1643 * Output: None
1644 *
1645 * Side Effects: None
1646 *
1647 * Overview: MACPowerDown puts the MRF24WB0M in low power sleep mode. In
1648 * sleep mode, no packets can be transmitted or received.
1649 * All MAC and PHY registers should not be accessed.
1650 *
1651 * Note: If a packet is being transmitted while this function is
1652 * called, this function will block until it is it complete.
1653 * If anything is being received, it will be completed.
1654 *****************************************************************************/
1655 void MACPowerDown(void)
1656 {
1657 }//end MACPowerDown
1658  
1659  
1660 /******************************************************************************
1661 * Function: void MACPowerUp(void)
1662 *
1663 * PreCondition: SPI bus must be initialized (done in MACInit()).
1664 *
1665 * Input: None
1666 *
1667 * Output: None
1668 *
1669 * Side Effects: None
1670 *
1671 * Overview: MACPowerUp returns the MRF24WB0M back to normal operation
1672 * after a previous call to MACPowerDown(). Calling this
1673 * function when already powered up will have no effect.
1674 *
1675 * Note: If a link partner is present, it will take 10s of
1676 * milliseconds before a new link will be established after
1677 * waking up. While not linked, packets which are
1678 * transmitted will most likely be lost. MACIsLinked() can
1679 * be called to determine if a link is established.
1680 *****************************************************************************/
1681 void MACPowerUp(void)
1682 {
1683 }//end MACPowerUp
1684  
1685 #if 0
1686 /* Not needed for MCHP */
1687  
1688 void RawSendUntamperedData(UINT8 *pReq, UINT16 len)
1689 {
1690 BOOL res;
1691 UINT8 preambleBuf[2];
1692 UINT16 byteCount;
1693  
1694 if (GetTxRawWindowState() == WF_RAW_DATA_MOUNTED)
1695 {
1696 WF_ASSERT(FALSE);
1697 }
1698  
1699 // RAW memory alloc
1700 res = AllocateDataTxBuffer(len);
1701  
1702 /* if could not allocate enough bytes */
1703 if (res != TRUE)
1704 {
1705 // Release whatever has been allocated.
1706 DeallocateDataTxBuffer();
1707 WF_ASSERT(FALSE);
1708 }
1709  
1710 /* fill out 2 byte preamble of request message */
1711 preambleBuf[0] = WF_DATA_REQUEST_TYPE; // indicate this is a data msg
1712 preambleBuf[1] = WF_UNTAMPERED_DATA_MSG_SUBTYPE; // untampered data subtype
1713  
1714 /* write out preamble */
1715 RawWrite(RAW_TX_ID, 0, sizeof(preambleBuf), preambleBuf);
1716  
1717 // write out payload
1718 RawSetByte(RAW_TX_ID, (UINT8 *) pReq, len);
1719  
1720 // Instruct WF chip to transmit the packet data in the raw window
1721 RawSendTxBuffer(len + sizeof(preambleBuf));
1722  
1723 }
1724 #endif
1725  
1726 #else
1727 /* dummy func to keep C18 compiler happy when module has no executeable code */
1728 void WFMac_EmptyFunc(void)
1729 {
1730 ;
1731 }
1732 #endif /* WF_CS_TRIS*/
1733  
1734  
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3