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 |
Powered by WebSVN v2.8.3