| 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