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

library

?curdirlinks? -

Blame information for rev 32

Line No. Rev Author Line
1 32 kaklik /*********************************************************************
2 *
3 * MAC Module (Microchip PIC32MX5-7) for Microchip TCP/IP Stack
4 *
5 *********************************************************************
6 * FileName: ETHPIC32IntMac.c
7 * Dependencies: see the include section below
8 *
9 * Processor: PIC32MX
10 *
11 * Company: Microchip Technology, Inc.
12 *
13 * Software License Agreement
14 *
15 * The software supplied herewith by Microchip Technology Incorporated
16 * (the “Company”) for its PICmicro® Microcontroller is intended and
17 * supplied to you, the Company’s customer, for use solely and
18 * exclusively on Microchip PICmicro Microcontroller products. The
19 * software is owned by the Company and/or its supplier, and is
20 * protected under applicable copyright laws. All rights are reserved.
21 * Any use in violation of the foregoing restrictions may subject the
22 * user to criminal sanctions under applicable laws, as well as to
23 * civil liability for the breach of the terms and conditions of this
24 * license.
25 *
26 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
27 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
28 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
29 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
30 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
31 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
32 *
33 * $Id: $
34 *
35 ********************************************************************/
36 #include <string.h>
37  
38 #include "GenericTypeDefs.h"
39  
40 #include "TCPIP Stack/TCPIP.h"
41 #include "TCPIP Stack/MAC.h"
42  
43  
44 // Compile only for PIC32MX with Ethernet MAC interface (must not have external ENCX24J600, ENC28J60, or ZG2100M hardware defined)
45 #if defined(__PIC32MX__) && defined(_ETH) && !defined(ENC100_INTERFACE_MODE) && !defined(ENC_CS_TRIS) && !defined(ZG_CS_TRIS)
46  
47 // running on PIC32MX5-7 family with embedded ETHC
48  
49 #include <peripheral/eth.h>
50  
51 #include "TCPIP Stack/ETHPIC32ExtPhy.h"
52  
53  
54 /** D E F I N I T I O N S ****************************************************/
55  
56  
57 #define ETHER_IP (0x00u)
58 #define ETHER_ARP (0x06u)
59  
60  
61 #define LINK_REFRESH_MS 100 // refresh link status time, ms
62  
63 typedef struct
64 {
65 int txBusy; // busy flag
66 unsigned int dataBuff[(MAC_TX_BUFFER_SIZE+sizeof(ETHER_HEADER)+sizeof(int)-1)/sizeof(int)]; // actual data buffer
67 }sEthTxDcpt; // TX buffer descriptor
68  
69 /******************************************************************************
70 * Prototypes
71 ******************************************************************************/
72 static void _TxAckCallback(void* pPktBuff, int buffIx); // Eth tx buffer acnowledge function
73 static int _LinkReconfigure(void); // link reconfiguration
74  
75  
76 // TX buffers
77 static volatile sEthTxDcpt _TxDescriptors[EMAC_TX_DESCRIPTORS]; // the statically allocated TX buffers
78 static volatile sEthTxDcpt* _pTxCurrDcpt=0; // the current TX buffer
79 static int _TxLastDcptIx=0; // the last TX descriptor used
80 static unsigned short int _TxCurrSize=0; // the current TX buffer size
81  
82  
83 // RX buffers
84 static unsigned char _RxBuffers[EMAC_RX_DESCRIPTORS][EMAC_RX_BUFF_SIZE]; // rx buffers for incoming data
85 static unsigned char* _pRxCurrBuff=0; // the current RX buffer
86 static unsigned short int _RxCurrSize=0; // the current RX buffer size
87  
88  
89  
90 // HTTP +SSL buffers
91 static unsigned char _HttpSSlBuffer[RESERVED_HTTP_MEMORY+RESERVED_SSL_MEMORY];
92  
93  
94 // general stuff
95 static unsigned char* _CurrWrPtr=0; // the current write pointer
96 static unsigned char* _CurrRdPtr=0; // the current read pointer
97  
98  
99 // timing and link status maintenance
100 static DWORD _linkUpdTick; // last tick value when the link update was started
101 static eEthLinkStat _linkPrev; // last value of the link status
102 static int _linkPresent; // if connection to the PHY properly detected
103 static int _linkNegotiation; // if an auto-negotiation is in effect
104  
105 // run time statistics
106 /*static*/ int _stackMgrRxOkPkts=0;
107 /*static*/ int _stackMgrRxBadPkts=0;
108 /*static*/ int _stackMgrInGetHdr=0;
109 /*static*/ int _stackMgrRxDiscarded=0;
110 /*static*/ int _stackMgrTxNotReady=0;
111  
112  
113 /*
114 * interface functions
115 *
116 */
117  
118  
119  
120  
121 /****************************************************************************
122 * Function: MACInit
123 *
124 * PreCondition: None
125 *
126 * Input: None
127 *
128 * Output: None
129 *
130 * Side Effects: None
131 *
132 * Overview: This function initializes the Eth controller, the MAC and the PHY. It should be called to be able to schedule
133 * any Eth transmit or receive operation.
134 *
135 * Note: None
136 *****************************************************************************/
137 void MACInit(void)
138 {
139 union
140 {
141 double align; // alignement
142 BYTE addr[6]; // address itself
143 }SysMACAddr; // aligned MAC address
144  
145 int ix;
146 eEthRes ethRes, phyInitRes;
147 BYTE useFactMACAddr[6] = {0x00, 0x04, 0xa3, 0x00, 0x00, 0x00}; // to check if factory programmed MAC address needed
148 BYTE unsetMACAddr[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; // not set MAC address
149  
150 int initFail=0;
151  
152 _stackMgrRxBadPkts=_stackMgrRxOkPkts=_stackMgrInGetHdr=_stackMgrRxDiscarded=0;
153 _CurrWrPtr=_CurrRdPtr=0;
154  
155 // set the TX/RX pointers
156 for(ix=0; ix<sizeof(_TxDescriptors)/sizeof(*_TxDescriptors); ix++)
157 {
158 _TxDescriptors[ix].txBusy=0;
159 }
160 _pTxCurrDcpt=_TxDescriptors+0; _TxLastDcptIx=0; _TxCurrSize=0;
161  
162 _pRxCurrBuff=0; _RxCurrSize=0;
163  
164 _linkNegotiation=_linkPresent=0;
165 _linkPrev=ETH_LINK_ST_DOWN;
166  
167  
168 while(1)
169 {
170 eEthLinkStat linkStat;
171 eEthOpenFlags oFlags, linkFlags;
172 eMacPauseType pauseType;
173 eEthPhyCfgFlags cfgFlags;
174  
175  
176  
177 #ifdef PHY_RMII
178 cfgFlags=ETH_PHY_CFG_RMII;
179 #else
180 cfgFlags=ETH_PHY_CFG_MII;
181 #endif
182  
183 #ifdef PHY_CONFIG_ALTERNATE
184 cfgFlags|=ETH_PHY_CFG_ALTERNATE;
185 #else
186 cfgFlags|=ETH_PHY_CFG_DEFAULT;
187 #endif
188  
189  
190 #if ETH_CFG_LINK
191 oFlags=ETH_CFG_AUTO?ETH_OPEN_AUTO:0;
192 oFlags|=ETH_CFG_10?ETH_OPEN_10:0;
193 oFlags|=ETH_CFG_100?ETH_OPEN_100:0;
194 oFlags|=ETH_CFG_HDUPLEX?ETH_OPEN_HDUPLEX:0;
195 oFlags|=ETH_CFG_FDUPLEX?ETH_OPEN_FDUPLEX:0;
196 if(ETH_CFG_AUTO_MDIX)
197 {
198 oFlags|=ETH_OPEN_MDIX_AUTO;
199 }
200 else
201 {
202 oFlags|=ETH_CFG_SWAP_MDIX?ETH_OPEN_MDIX_SWAP:ETH_OPEN_MDIX_NORM;
203 }
204 #else
205 oFlags= ETH_OPEN_DEFAULT;
206 #endif // ETH_CFG_LINK
207  
208  
209 pauseType=(oFlags&ETH_OPEN_FDUPLEX)?MAC_PAUSE_CPBL_MASK:MAC_PAUSE_TYPE_NONE;
210  
211 // start the initialization sequence
212 EthInit();
213  
214 phyInitRes=EthPhyInit(oFlags, cfgFlags, &linkFlags);
215  
216 // let the auto-negotiation (if any) take place
217 // continue the initialization
218 EthRxFiltersClr(ETH_FILT_ALL_FILTERS);
219 EthRxFiltersSet(ETH_FILT_CRC_ERR_REJECT|ETH_FILT_RUNT_REJECT|ETH_FILT_ME_UCAST_ACCEPT|ETH_FILT_MCAST_ACCEPT|ETH_FILT_BCAST_ACCEPT);
220  
221  
222 // set the MAC address
223 memcpy(SysMACAddr.addr, AppConfig.MyMACAddr.v, sizeof(SysMACAddr.addr));
224 if(memcmp(SysMACAddr.addr, useFactMACAddr, sizeof(useFactMACAddr))==0 || memcmp(SysMACAddr.addr, unsetMACAddr, sizeof(unsetMACAddr))==0 )
225 { // use the factory programmed address existent in the MAC
226 unsigned short* pS=(unsigned short*)SysMACAddr.addr;
227 *pS++=EMACxSA2;
228 *pS++=EMACxSA1;
229 *pS=EMACxSA0;
230 memcpy(AppConfig.MyMACAddr.v, SysMACAddr.addr, sizeof(SysMACAddr.addr));
231 }
232 else
233 { // use the supplied address
234 EthMACSetAddress(SysMACAddr.addr);
235 }
236  
237 if(EthDescriptorsAdd(EMAC_TX_DESCRIPTORS, ETH_DCPT_TYPE_TX, 0)!=EMAC_TX_DESCRIPTORS)
238 {
239 initFail++;
240 }
241  
242 if(EthDescriptorsAdd(EMAC_RX_DESCRIPTORS, ETH_DCPT_TYPE_RX, 0)!=EMAC_RX_DESCRIPTORS)
243 {
244 initFail++;
245 }
246  
247 EthRxSetBufferSize(EMAC_RX_BUFF_SIZE);
248  
249 // set the RX buffers as permanent receive buffers
250 for(ix=0, ethRes=ETH_RES_OK; ix<EMAC_RX_DESCRIPTORS && ethRes==ETH_RES_OK; ix++)
251 {
252 unsigned char* pRxBuff=_RxBuffers[ix];
253 ethRes=EthRxBuffersAppend(&pRxBuff, 1, BUFF_FLAG_RX_STICKY);
254 }
255  
256 if(ethRes!=ETH_RES_OK)
257 {
258 initFail++;
259 }
260  
261  
262 if(phyInitRes==ETH_RES_OK)
263 { // PHY was detected
264 _linkPresent=1;
265 if(oFlags&ETH_OPEN_AUTO)
266 { // we'll just wait for the negotiation to be done
267 _linkNegotiation=1; // performing the negotiation
268 linkStat=_LinkReconfigure()?ETH_LINK_ST_UP:ETH_LINK_ST_DOWN; // if negotiation not done yet we need to try it next time
269 }
270 else
271 { // no need of negotiation results; just update the MAC
272 EthMACOpen(linkFlags, pauseType);
273 linkStat=EthPhyGetLinkStatus(0);
274 }
275  
276 _linkUpdTick=TickGet(); // the last time we performed the link read
277 _linkPrev=linkStat;
278 }
279 else
280 {
281 initFail++;
282 }
283  
284 break;
285 }
286  
287  
288 // return !initFail; // at this point initFail gives some indication of any existent problems
289  
290 }
291  
292  
293 /****************************************************************************
294 * Function: MACIsLinked
295 *
296 * PreCondition: None
297 *
298 * Input: None
299 *
300 * Output: TRUE if link is up
301 * FALSE otherwise
302 *
303 * Side Effects: None
304 *
305 * Overview: This function checks the link status
306 *
307 * Note: None
308 *****************************************************************************/
309 BOOL MACIsLinked(void)
310 {
311 return (_linkPrev&ETH_LINK_ST_UP)!=0;
312 }
313  
314  
315 /****************************************************************************
316 * Function: MACGetTxBaseAddr
317 *
318 * PreCondition: None
319 *
320 * Input: None
321 *
322 * Output: TX buffer base address
323 *
324 * Side Effects: None
325 *
326 * Overview: This function returns the address of the current TX buffer.
327 *
328 * Note: The returned value could be 0 if currently there's no available TX buffer.
329 *****************************************************************************/
330 PTR_BASE MACGetTxBaseAddr(void)
331 {
332 return _pTxCurrDcpt?(PTR_BASE)_pTxCurrDcpt->dataBuff:0;
333 }
334  
335 /****************************************************************************
336 * Function: MACGetHttpBaseAddr
337 *
338 * PreCondition: None
339 *
340 * Input: None
341 *
342 * Output: HTTP buffer base address
343 *
344 * Side Effects: None
345 *
346 * Overview: This function returns the address of the HTTP buffer.
347 *
348 * Note: The HTTP buffer is a static one, always available.
349 *****************************************************************************/
350 PTR_BASE MACGetHttpBaseAddr(void)
351 {
352 return (PTR_BASE)_HttpSSlBuffer;
353 }
354  
355 /****************************************************************************
356 * Function: MACGetSslBaseAddr
357 *
358 * PreCondition: None
359 *
360 * Input: None
361 *
362 * Output: SSL buffer base address
363 *
364 * Side Effects: None
365 *
366 * Overview: This function returns the address of the SSL buffer.
367 *
368 * Note: The SSL buffer is a static one, always available.
369 *****************************************************************************/
370 PTR_BASE MACGetSslBaseAddr(void)
371 {
372 return (PTR_BASE)(_HttpSSlBuffer+RESERVED_HTTP_MEMORY);
373 }
374  
375  
376 /**************************
377 * TX functions
378 ***********************************************/
379  
380 /****************************************************************************
381 * Function: MACSetWritePtr
382 *
383 * PreCondition: None
384 *
385 * Input: None
386 *
387 * Output: old write pointer
388 *
389 * Side Effects: None
390 *
391 * Overview: This function sets the new write pointer.
392 *
393 * Note: None
394 *****************************************************************************/
395 PTR_BASE MACSetWritePtr(PTR_BASE address)
396 {
397 unsigned char* oldPtr;
398  
399 oldPtr=_CurrWrPtr;
400 _CurrWrPtr=(unsigned char*)address;
401 return (PTR_BASE)oldPtr;
402 }
403  
404  
405 /******************************************************************************
406 * Function: BOOL MACIsTxReady(void)
407 *
408 * PreCondition: None
409 *
410 * Input: None
411 *
412 * Output: TRUE: If data can be inserted in the current TX buffer
413 * FALSE: there is no free TX buffer
414 *
415 * Side Effects: None
416 *
417 * Overview: Checks if there is an available current TX buffer
418 *
419 * Note: None
420 *****************************************************************************/
421 BOOL MACIsTxReady(void)
422 {
423 int ix;
424  
425 EthTxAckBuffer(0, _TxAckCallback); // acknowledge everything
426  
427 if(_pTxCurrDcpt==0)
428 {
429 for(ix=_TxLastDcptIx+1; ix<sizeof(_TxDescriptors)/sizeof(*_TxDescriptors); ix++)
430 {
431 if(_TxDescriptors[ix].txBusy==0)
432 { // found a non busy descriptor
433 _pTxCurrDcpt=_TxDescriptors+ix;
434 _TxLastDcptIx=ix;
435 break;
436 }
437 }
438 if(_pTxCurrDcpt==0)
439 {
440 for(ix=0; ix<_TxLastDcptIx; ix++)
441 {
442 if(_TxDescriptors[ix].txBusy==0)
443 { // found a non busy descriptor
444 _pTxCurrDcpt=_TxDescriptors+ix;
445 _TxLastDcptIx=ix;
446 break;
447 }
448 }
449 }
450 }
451  
452  
453 if( _pTxCurrDcpt==0)
454 {
455 _stackMgrTxNotReady++;
456 }
457  
458 return _pTxCurrDcpt!=0;
459 }
460  
461 /******************************************************************************
462 * Function: void MACPut(BYTE val)
463 *
464 * PreCondition: None
465 *
466 * Input: byte to be written
467 *
468 * Output: None
469 *
470 * Side Effects: None
471 *
472 * Overview: Writes a byte to the current write location and increments the write pointer.
473 *
474 * Note: None
475 *****************************************************************************/
476 void MACPut(BYTE val)
477 {
478 *_CurrWrPtr++=val;
479 }
480  
481 /******************************************************************************
482 * Function: void MACPutArray(BYTE* buff, WORD len)
483 *
484 * PreCondition: None
485 *
486 * Input: buff - buffer to be written
487 * len - buffer length
488 *
489 * Output: None
490 *
491 * Side Effects: None
492 *
493 * Overview: Writes a buffer to the current write location and updates the write pointer.
494 *
495 * Note: None
496 *****************************************************************************/
497 void MACPutArray(BYTE *buff, WORD len)
498 {
499 memcpy(_CurrWrPtr, buff, len);
500 _CurrWrPtr+=len;
501 }
502  
503  
504 /******************************************************************************
505 * Function: void MACPutHeader(MAC_ADDR *remote, BYTE type, WORD dataLen)
506 *
507 * PreCondition: None
508 *
509 * Input: remote - Pointer to memory which contains the destination MAC address (6 bytes)
510 * type - packet type: MAC_IP or ARP
511 * dataLen - ethernet frame payload
512 *
513 * Output: None
514 *
515 * Side Effects: None
516 *
517 * Overview: Sets the write pointer at the beginning of the current TX buffer
518 * and sets the ETH header and the frame length. Updates the write pointer
519 *
520 * Note: Assumes there is an available TX buffer, i.e. MACIsTxReady() returned !0
521 *****************************************************************************/
522 void MACPutHeader(MAC_ADDR *remote, BYTE type, WORD dataLen)
523 {
524 _TxCurrSize=dataLen+sizeof(ETHER_HEADER);
525 _CurrWrPtr=(unsigned char*)_pTxCurrDcpt->dataBuff; // point at the beg of the buffer
526  
527  
528 memcpy(_CurrWrPtr, remote, sizeof(*remote));
529 _CurrWrPtr+=sizeof(*remote);
530 memcpy(_CurrWrPtr, &AppConfig.MyMACAddr, sizeof(AppConfig.MyMACAddr));
531 _CurrWrPtr+=sizeof(AppConfig.MyMACAddr);
532  
533  
534 *_CurrWrPtr++=0x08;
535 *_CurrWrPtr++=(type == MAC_IP) ? ETHER_IP : ETHER_ARP;
536  
537 }
538  
539  
540  
541 void MACFlush(void)
542 {
543 if(_pTxCurrDcpt && _TxCurrSize)
544 { // there is a buffer to transmit
545 _pTxCurrDcpt->txBusy=1;
546 EthTxSendBuffer((void*)_pTxCurrDcpt->dataBuff, _TxCurrSize);
547 // res should be ETH_RES_OK since we made sure we had a descriptor available
548 // by the call to MACIsTxReady and the number of the buffers matches the number of descriptors
549 _pTxCurrDcpt=0;
550 _TxCurrSize=0;
551 }
552 }
553  
554 /**************************
555 * RX functions
556 ***********************************************/
557  
558  
559 /******************************************************************************
560 * Function: void MACDiscardRx(void)
561 *
562 * PreCondition: None
563 *
564 * Input: None
565 *
566 * Output: None
567 *
568 * Side Effects: None
569 *
570 * Overview: Marks the last received packet (obtained using
571 * MACGetHeader())as being processed and frees the buffer
572 * memory associated with it.
573 * It acknowledges the ETHC.
574 *
575 * Note: Is is safe to call this function multiple times between
576 * MACGetHeader() calls. Extra packets won't be thrown away
577 * until MACGetHeader() makes it available.
578 *****************************************************************************/
579 void MACDiscardRx(void)
580 {
581 if(_pRxCurrBuff)
582 { // an already existing packet
583 EthRxAckBuffer(_pRxCurrBuff, 0);
584 _pRxCurrBuff=0;
585 _RxCurrSize=0;
586  
587 _stackMgrRxDiscarded++;
588 }
589 }
590  
591  
592  
593 /******************************************************************************
594 * Function: BOOL MACGetHeader(MAC_ADDR *remote, BYTE* type)
595 *
596 * PreCondition: None
597 *
598 * Input: *remote: Location to store the Source MAC address of the
599 * received frame.
600 * *type: Location of a BYTE to store the constant
601 * MAC_UNKNOWN, ETHER_IP, or ETHER_ARP, representing
602 * the contents of the Ethernet type field.
603 *
604 * Output: TRUE: If a packet was waiting in the RX buffer. The
605 * remote, and type values are updated.
606 * FALSE: If a packet was not pending. remote and type are
607 * not changed.
608 *
609 * Side Effects: Last packet is discarded if MACDiscardRx() hasn't already
610 * been called.
611 *
612 * Overview: None
613 *
614 * Note: Sets the read pointer at the beginning of the new packet
615 *****************************************************************************/
616 BOOL MACGetHeader(MAC_ADDR *remote, BYTE* type)
617 {
618 void* pNewPkt;
619 const sRxPktStat* pRxPktStat;
620 eEthRes res;
621  
622 _stackMgrInGetHdr++;
623  
624 // verify the link status
625 // if auto negotiation is enabled we may have to reconfigure the MAC
626  
627 while(_linkPresent)
628 {
629 eEthLinkStat linkCurr;
630 DWORD currTick=TickGet();
631  
632 if(currTick-_linkUpdTick< (TICKS_PER_SECOND/1000)*LINK_REFRESH_MS)
633 { // not time to do anything yet
634 break;
635 }
636  
637 linkCurr=EthPhyGetLinkStatus(0); // read current PHY status
638 _linkUpdTick=currTick; // start a new counting period
639  
640 if(_linkNegotiation)
641 { // the auto-negotiation turned on
642 if((linkCurr&ETH_LINK_ST_UP) && !(_linkPrev&ETH_LINK_ST_UP))
643 { // we're up after being done. do renegotiate!
644 linkCurr=_LinkReconfigure()?ETH_LINK_ST_UP:ETH_LINK_ST_DOWN; // if negotiation not done yet we need to try it next time
645 }
646 // else link went/still down; nothing to do yet
647 }
648 _linkPrev=linkCurr;
649  
650 break;
651 }
652  
653  
654 MACDiscardRx(); // discard/acknowledge the old RX buffer, if any
655  
656 res=EthRxGetBuffer(&pNewPkt, &pRxPktStat);
657  
658 if(res==ETH_RES_OK)
659 { // available packet; minimum check
660  
661 if(pRxPktStat->rxOk && !pRxPktStat->runtPkt && !pRxPktStat->crcError)
662 { // valid packet;
663 WORD_VAL newType;
664 _RxCurrSize=pRxPktStat->rxBytes;
665 _pRxCurrBuff=pNewPkt;
666 _CurrRdPtr=_pRxCurrBuff+sizeof(ETHER_HEADER); // skip the packet header
667 // set the packet type
668 memcpy(remote, &((ETHER_HEADER*)pNewPkt)->SourceMACAddr, sizeof(*remote));
669 *type=MAC_UNKNOWN;
670 newType=((ETHER_HEADER*)pNewPkt)->Type;
671 if( newType.v[0]==0x08 && (newType.v[1]==ETHER_IP || newType.v[1]==ETHER_ARP) )
672 {
673 *type=newType.v[1];
674 }
675  
676 _stackMgrRxOkPkts++;
677 }
678 }
679  
680 if(_pRxCurrBuff==0 && pNewPkt)
681 { // failed packet, discard
682 EthRxAckBuffer(pNewPkt, 0);
683 _stackMgrRxBadPkts++;
684 }
685  
686  
687 return _pRxCurrBuff!=0;
688 }
689  
690  
691  
692 /******************************************************************************
693 * Function: void MACSetReadPtrInRx(WORD offset)
694 *
695 * PreCondition: A packet has been obtained by calling MACGetHeader() and
696 * getting a TRUE result.
697 *
698 * Input: offset: WORD specifying how many bytes beyond the Ethernet
699 * header's type field to relocate the read pointer.
700 *
701 * Output: None
702 *
703 * Side Effects: None
704 *
705 * Overview: The current read pointer is updated. All calls to
706 * MACGet() and MACGetArray() will use these new values.
707 *
708 * Note:
709 ******************************************************************************/
710 void MACSetReadPtrInRx(WORD offset)
711 {
712 _CurrRdPtr=_pRxCurrBuff+sizeof(ETHER_HEADER)+offset;
713 }
714  
715  
716 /****************************************************************************
717 * Function: MACSetReadPtr
718 *
719 * PreCondition: None
720 *
721 * Input: None
722 *
723 * Output: old read pointer
724 *
725 * Side Effects: None
726 *
727 * Overview: This function sets the new read pointer value.
728 *
729 * Note: None
730 *****************************************************************************/
731 PTR_BASE MACSetReadPtr(PTR_BASE address)
732 {
733 unsigned char* oldPtr;
734  
735 oldPtr=_CurrRdPtr;
736 _CurrRdPtr=(unsigned char*)address;
737 return (PTR_BASE)oldPtr;
738 }
739  
740  
741  
742  
743 /******************************************************************************
744 * Function: BYTE MACGet()
745 *
746 * PreCondition: A valid packet should vahe been obtained or the read pointer properly set.
747 *
748 * Input: None
749 *
750 * Output: Byte read from the current read pointer location
751 *
752 * Side Effects: None
753 *
754 * Overview: MACGet returns the byte pointed to by the current read pointer location and
755 * increments the read pointer.
756 *
757 * Note: None
758 *****************************************************************************/
759 BYTE MACGet(void)
760 {
761 return *_CurrRdPtr++;
762 }
763  
764  
765 /******************************************************************************
766 * Function: WORD MACGetArray(BYTE *address, WORD len)
767 *
768 * PreCondition: A valid packet should vahe been obtained or the read pointer properly set.
769 *
770 * Input: address: Pointer to storage location
771 * len: Number of bytes to read from the data buffer.
772 *
773 * Output: number of bytes copied to the data buffer.
774 *
775 * Side Effects: None
776 *
777 * Overview: Copies data in the supplied buffer.
778 *
779 * Note: The read pointer is updated
780 *****************************************************************************/
781 WORD MACGetArray(BYTE *address, WORD len)
782 {
783 if(address)
784 {
785 memcpy(address, _CurrRdPtr, len);
786 }
787  
788 _CurrRdPtr+=len;
789 return len;
790 }
791  
792 /******************************************************************************
793 * Function: WORD MACGetFreeRxSize(void)
794 *
795 * PreCondition: None
796 *
797 * Input: None
798 *
799 * Output: An estimate of how much RX buffer space is free at the present time.
800 *
801 * Side Effects: None
802 *
803 * Overview: None
804 *
805 * Note: None
806 *****************************************************************************/
807 WORD MACGetFreeRxSize(void)
808 {
809 int avlblRxBuffs=sizeof(_RxBuffers)/sizeof(*_RxBuffers)-EthDescriptorsGetRxUnack(); // avlbl=allBuffs-unAck
810  
811 return avlblRxBuffs*(sizeof(_RxBuffers[0])/sizeof(*_RxBuffers[0])); // avlbl* sizeof(buffer)
812 }
813  
814  
815 /*****************************************************************************
816 Function:
817  
818  
819 Summary:
820 Asynchronously copies data from one address to another within the Ethernet memory.
821  
822 Description:
823  
824  
825 Precondition:
826 SPI bus must be initialized (done in MACInit()).
827  
828  
829 Returns:
830 None
831  
832 Remarks:
833 Call MACIsMemCopyDone() to see when the transfer is complete.
834  
835 Copying to a destination region that overlaps with the source address
836 is supported only if the destination start address is at a lower memory
837 address (closer to 0x0000) than the source pointer. However, if they do
838 overlap there must be at least 2 bytes of non-overlap to ensure correct
839 results due to hardware DMA requirements. For example, destAddr = 0;
840 sourceAddr = 1; is illegal while destAddr = 0; sourceAddr = 2; is fine.
841  
842 If a prior transfer is already in progress prior to calling this function,
843 this function will block until it can start this transfer.
844  
845 If a negative value is used for the sourceAddr or destAddr parameters,
846 then that pointer will get updated with the next address after the read or
847 write.
848 *****************************************************************************/
849  
850  
851 /******************************************************************************
852 * Function: void MACMemCopyAsync(PTR_BASE destAddr, PTR_BASE sourceAddr, WORD len)
853 *
854 * PreCondition: Read and write pointers properly set if using the current ponter values
855 *
856 * Input: destAddr - Destination address in the memory to copy to. If it equals -1,
857 * the current write pointer will be used.
858 * sourceAddr - Source address to read from. If it equals -1,
859 * the current read pointer will be used.
860 * len - number of bytes to copy
861 *
862 * Output: None
863 *
864 * Side Effects: None
865 *
866 * Overview: Copies data from one address to another within the Ethernet memory.
867 * Overlapped memory regions are allowed only if the destination start address
868 * is at a lower memory address than the source address.
869 *
870 * Note: The addresses do not have to be aligned.
871 *****************************************************************************/
872 void MACMemCopyAsync(PTR_BASE destAddr, PTR_BASE sourceAddr, WORD len)
873 {
874 if(len)
875 {
876 unsigned char *pDst, *pSrc;
877  
878 pDst=(destAddr==-1)?_CurrWrPtr:(unsigned char*)destAddr;
879 pSrc=(sourceAddr==-1)?_CurrRdPtr:(unsigned char*)sourceAddr;
880  
881 memcpy(pDst, pSrc, len);
882  
883 }
884 }
885  
886 /******************************************************************************
887 * Function: void MACIsMemCopyDone(void)
888 *
889 * PreCondition: None
890 *
891 * Input: None
892 *
893 * Output: TRUE
894 *
895 * Side Effects: None
896 *
897 * Overview: Since there's no copy initiated by the DMA, the function returns always true for now.
898 *
899 * Note: None
900 *****************************************************************************/
901 BOOL MACIsMemCopyDone(void)
902 {
903 return 1;
904 }
905  
906  
907 /******************************************************************************
908 * Function: WORD CalcIPBufferChecksum(WORD len)
909 *
910 * PreCondition: Read buffer pointer set to starting of checksum data
911 *
912 * Input: len: Total number of bytes to calculate the checksum over.
913 *
914 * Output: 16-bit checksum as defined by RFC 793
915 *
916 * Side Effects: None
917 *
918 * Overview: This function performs a checksum calculation of the buffer
919 * pointed by the current value of the read pointer.
920 *
921 * Note: None
922 *****************************************************************************/
923 WORD CalcIPBufferChecksum(WORD len)
924 {
925 return CalcIPChecksum(_CurrRdPtr, len);
926 }
927  
928  
929 /******************************************************************************
930 * Function: WORD MACCalcRxChecksum(WORD offset, WORD len)
931 *
932 * PreCondition: None
933 *
934 * Input: offset - Number of bytes beyond the beginning of the
935 * Ethernet data (first byte after the type field)
936 * where the checksum should begin
937 * len - Total number of bytes to include in the checksum
938 *
939 * Output: 16-bit checksum as defined by RFC 793.
940 *
941 * Side Effects: None
942 *
943 * Overview: This function performs a checksum calculation in the current receive buffer.
944 *
945 * Note: None
946 *****************************************************************************/
947 WORD MACCalcRxChecksum(WORD offset, WORD len)
948 {
949 return CalcIPChecksum(_pRxCurrBuff+sizeof(ETHER_HEADER)+offset, len);
950 }
951  
952  
953 /**************************
954 * local functions and helpers
955 ***********************************************/
956  
957 /*********************************************************************
958 * Function: void _TxAckCallback(void* pPktBuff)
959 *
960 * PreCondition: None
961 *
962 * Input: pPktBuff - tx buffer to be acknowledged
963 *
964 * Output: None
965 *
966 * Side Effects: None
967 *
968 * Overview: TX acknowledge call back function.
969 * Called by the Eth MAC when TX buffers are acknoledged (as a result of a call to EthTxAckBuffer).
970 *
971 * Note: None
972 ********************************************************************/
973 static void _TxAckCallback(void* pPktBuff, int buffIx)
974 {
975 volatile sEthTxDcpt* pDcpt;
976  
977 pDcpt=(sEthTxDcpt*)((char*)pPktBuff-offsetof(sEthTxDcpt, dataBuff));
978  
979 pDcpt->txBusy=0;
980  
981 }
982  
983  
984 /*********************************************************************
985 * Function: int _LinkReconfigure(void)
986 *
987 * PreCondition: None
988 *
989 * Input: None
990 *
991 * Output: TRUE if negotiation succeeded and MAC was updated
992 * FALSE otherwise
993 *
994 * Side Effects: None
995 *
996 * Overview: Performs re-configuration after auto-negotiation performed.
997 *
998 * Note: None
999 ********************************************************************/
1000 static int _LinkReconfigure(void)
1001 {
1002  
1003 eEthOpenFlags linkFlags;
1004 eEthLinkStat linkStat;
1005 eMacPauseType pauseType;
1006 eEthRes phyRes;
1007 int success=0;
1008  
1009  
1010 phyRes=EthPhyNegotiationComplete(0); // see if negotiation complete
1011 if(phyRes==ETH_RES_OK)
1012 {
1013 linkStat=EthPhyGetNegotiationResult(&linkFlags, &pauseType);
1014 if(linkStat&ETH_LINK_ST_UP)
1015 { // negotiation succeeded; properly update the MAC
1016 #ifdef PHY_RMII
1017 EthMIIMInit(GetSystemClock(), EthPhyMIIMClock(), linkFlags, 1);
1018 #else
1019 EthMIIMInit(GetSystemClock(), EthPhyMIIMClock(), linkFlags, 0);
1020 #endif
1021 EthMACOpen(linkFlags, pauseType);
1022 success=1;
1023 }
1024 }
1025  
1026 return success;
1027 }
1028  
1029  
1030  
1031 #endif // defined(__PIC32MX__) && defined(_ETH)
1032  
1033  
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3