/[H8]/trunk/docs/MCHPStack2.20/Source/SMSC91C111.c
ViewVC logotype

Annotation of /trunk/docs/MCHPStack2.20/Source/SMSC91C111.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (hide annotations) (download)
Tue May 1 08:17:39 2007 UTC (17 years, 2 months ago) by hedin
File MIME type: text/plain
File size: 24026 byte(s)
Removed tcpip stack 4.02 and added tcpip stack 2.20.
1 hedin 62 /*********************************************************************
2     *
3     * MAC Module (SMSC LAN91C111) for Microchip TCP/IP Stack
4     *
5     *********************************************************************
6     * FileName: SMSC91C111.c
7     * Dependencies: string.h
8     * stacktsk.h
9     * helpers.h
10     * mac.h
11     * Processor: PIC18
12     * Complier: MCC18 v1.00.50 or higher
13     * HITECH PICC-18 V8.10PL1 or higher
14     * Company: Microchip Technology, Inc.
15     *
16     * Software License Agreement
17     *
18     * The software supplied herewith by Microchip Technology Incorporated
19     * (the “Company”) for its PICmicro® Microcontroller is intended and
20     * supplied to you, the Company’s customer, for use solely and
21     * exclusively on Microchip PICmicro Microcontroller products. The
22     * software is owned by the Company and/or its supplier, and is
23     * protected under applicable copyright laws. All rights are reserved.
24     * Any use in violation of the foregoing restrictions may subject the
25     * user to criminal sanctions under applicable laws, as well as to
26     * civil liability for the breach of the terms and conditions of this
27     * license.
28     *
29     * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
30     * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
31     * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
32     * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
33     * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
34     * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
35     *
36     *
37     * HiTech PICC18 Compiler Options excluding device selection:
38     * -FAKELOCAL -G -O -Zg -E -C
39     *
40     *
41     *
42     *
43     * Author Date Comment
44     *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45     * Nilesh Rajbharti 6/6/03 Original (Rev 1.0)
46     ********************************************************************/
47     #define THIS_IS_MAC_LAYER
48    
49     #include <string.h>
50     #include "stacktsk.h"
51     #include "helpers.h"
52     #include "mac.h"
53     #include "delay.h"
54    
55    
56     #if defined(STACK_USE_SLIP)
57     #error Unexpected module is detected.
58     #error This file must be linked when SLIP module is not in use.
59     #endif
60    
61    
62     /*
63     * Hardware interface to NIC.
64     */
65     #define NIC_CTRL_TRIS (TRISE)
66     #define NIC_RESET_IO (PORTE_RE2)
67     #define NIC_IOW_IO (PORTE_RE1)
68     #define NIC_IOR_IO (PORTE_RE0)
69     #define NIC_ADDR_IO (PORTB)
70     #define NIC_DATA_IO (PORTD)
71     #define SET_NIC_READ() (TRISD = 0xff)
72     #define SET_NIC_WRITE() (TRISD = 0x00)
73    
74     #define LB(a) (a.bits.b0)
75     #define UB(a) (a.bits.b4)
76    
77    
78     #define ETHER_IP (0x00)
79     #define ETHER_ARP (0x06)
80    
81     /* SMSC LAN91C111 register names and offsets */
82     #define RCR_LSB (0x04)
83     /* RCR_LSB bits */
84     #define ALMUL (0b00000100)
85     #define PRMS (0b00000010)
86     #define RX_ABORT (0b00000001)
87     #define RCR_MSB (RCR_LSB+1)
88    
89     /* RCR_MSB bits */
90     #define SOFT_RST (0b10000000)
91     #define FILT_CAR (0b01000000)
92     #define ABORT_ENB (0b00100000)
93     #define STRIP_CRC (0b00000010)
94     #define RXEN (0b00000001)
95    
96     #define TCR_LSB (0x00)
97    
98     #define EPHSR_LSB (0x02) // Bank 0
99     #define EPHSR_MSB (EPHSR_LSB+1)
100    
101     #define ECR_LSB (0x06) // Bank 0
102     #define ECR_MSB (ECR_LSB+1)
103     #define MIR_LSB (0x08) // Bank 0
104     #define MIR_MSB (MIR_LSB+1)
105    
106     #define IAR0 (0x04) // Bank 1
107     #define IAR1 (IAR0+1)
108     #define IAR2 (IAR0+2)
109     #define IAR3 (IAR0+3)
110     #define IAR4 (IAR0+4)
111     #define IAR5 (IAR0+5)
112    
113     #define CR_LSB (0x01) // Bank 1
114     #define CR_MSB (CR_LSB+1)
115     /* CR_MSB bits. */
116     #define EPH_POWER_EN (0b10000000)
117     #define NO_WAIT (0b00010000)
118     #define GPCNTRL (0b00000100)
119     #define EXT_PHY (0b00000010)
120    
121     #define BAR_LSB (0x02) // Bank 1
122     #define BAR_MSB (BAR_LSB+1)
123    
124     #define BSR_LSB (0x0e) // Always accessible
125     /* BSR_LSB bits */
126     #define BS2 (0b00000100)
127     #define BS1 (0b00000010)
128     #define BS0 (0b00000001)
129    
130     #define CTR_LSB (0x0C) // Bank 1
131     #define CTR_MSB (CTR_LSB+1)
132    
133     #define RPCR_LSB (0x0a)
134     #define RPCR_MSB (RPCR_LSB+1)
135    
136     #define MMUCR_LSB (0x0) // Bank2
137     #define MMUCR_MSB (MMUCR_LSB+1)
138    
139     /* Bits 7:5 of MMUCR_LSB */
140     #define NOOP (0b00000000)
141     #define ALLOCATE_TX (0b00100000)
142     #define MMU_RESET (0b01000000)
143     #define REMOVE_RX (0b01100000)
144     #define REMOVE_N_RELEASE_RX (0b10000000)
145     #define RELEASE_SPECIFIC_TX_PACKET (0b10100000)
146     #define ENQUE_TX_PACKET (0b11000000)
147     #define RESET_TX_FIFO (0b11100000)
148    
149     #define PNR (0x02) // Bank 2
150     #define ARR (PNR+1)
151    
152    
153     #define IST (0x0C)
154     #define ACK (0x0C)
155     #define MSK (0x0D) // Bank 2
156    
157     #define FIFO_LSB (0x4) // Bank 2
158     #define FIFO_MSB (FIFO_LSB+1)
159    
160     #define PTR_LSB (0x06)
161     #define PTR_MSB (PTR_LSB+1)
162    
163     #define DATA_LSB (0x08)
164    
165     #define MGMT_LSB (0x08) // Bank 3
166     /* Bit definition of MGMT_LSB */
167     #define MII_MDOE_HIGH (0b00001000)
168     #define MII_MDOE_LOW (0b00000000)
169     #define MII_MCLK_HIGH (0b00000100)
170     #define MII_MCLK_LOW (0b00000000)
171     #define MII_MDO_HIGH (0b00000001)
172     #define MII_MDO_LOW (0b00000000)
173    
174     #define MT_0 (0) // Bank 4
175     #define MT_1 (1)
176     #define MT_2 (2)
177     #define MT_3 (3)
178     #define MT_4 (4)
179     #define MT_5 (5)
180     #define MT_6 (6)
181     #define MT_7 (7)
182     #define MT_8 (8)
183    
184     /* Status and command bit defs for MII access */
185     #define MII_CMD_READ (0b01100000)
186     #define MII_CMD_WRITE (0b01010000)
187    
188     #define PHY_CONTROL (0b00000010)
189     #define PHY_STATUS (0b00000110)
190     #define PHY_ID1 (0b00001010)
191     #define PHY_ID2 (0b00001110)
192     #define PHY_ANEG_ADV (0b00010010)
193     #define PHY_ANEG_CAP (0b00010110)
194     #define PHY_CONFIG1 (0b01000010)
195     #define PHY_CONFIG2 (0b01000110)
196     #define PHY_STATUS_OUT (0b01001010)
197     #define PHY_MASK (0b01001110)
198    
199    
200     #define LEDA_10_100_LINK (0b00000000)
201     #define LEDA_10_LINK (0b01000000)
202     #define LEDA_FULL_DUPX (0b01100000)
203     #define LEDA_TX_RX (0b10000000)
204     #define LEDA_100_LINK (0b10100000)
205     #define LEDA_RX (0b11000000)
206     #define LEDA_TX (0b11100000)
207    
208     #define LEDB_10_100_LINK (0b00000000)
209     #define LEDB_10_LINK (0b00001000)
210     #define LEDB_FULL_DUPX (0b00001100)
211     #define LEDB_TX_RX (0b00010000)
212     #define LEDB_100_LINK (0b00010100)
213     #define LEDB_RX (0b00011000)
214     #define LEDB_TX (0b00011100)
215    
216    
217     #define LEDA_FUNCTION LEDA_10_100_LINK
218     #define LEDB_FUNCTION LEDB_TX_RX
219    
220    
221    
222     #define SelectBank(b) (NICPut(BSR_LSB, b))
223    
224     #define WRITE_NIC_ADDR(a) WriteNICAddr(a)
225    
226     typedef union _BYTE_VAL
227     {
228     struct
229     {
230     unsigned int b0:1;
231     unsigned int b1:1;
232     unsigned int b2:1;
233     unsigned int b3:1;
234     unsigned int b4:1;
235     unsigned int b5:1;
236     unsigned int b6:1;
237     unsigned int b7:1;
238     } bits;
239     BYTE Val;
240     } BYTE_VAL;
241    
242     typedef struct _DATA_BUFFER
243     {
244     struct
245     {
246     unsigned int bIsFree : 1;
247     } flags;
248     WORD_VAL length;
249     } DATA_BUFFER;
250    
251     static DATA_BUFFER TxBuffer;
252    
253     typedef struct _ETHER_HEADER
254     {
255     MAC_ADDR DestMACAddr;
256     MAC_ADDR SourceMACAddr;
257     WORD_VAL Type;
258     } ETHER_HEADER;
259    
260    
261    
262     BYTE NICCurrentRdPtr; // Page that is being read...
263     BYTE NICCurrentTxBuffer;
264    
265    
266     static void NICReset(void);
267     static void NICPut(BYTE reg, BYTE val);
268     static BYTE NICGet(BYTE reg);
269     static void WriteNICAddr(BYTE addr);
270     static void MIIBeginCommand(BYTE command, BYTE reg);
271     static void PHYPut(BYTE addr, WORD val);
272     static WORD PHYGet(BYTE addr);
273     static BYTE MIIGet(BYTE data);
274     static void MIIPut(BYTE data, BYTE bitCount);
275     static BUFFER AllocateTxBuffer(void);
276    
277     void MACInit(void)
278     {
279     BYTE_VAL tempByte;
280     WORD_VAL tempWord;
281    
282    
283     TxBuffer.flags.bIsFree = TRUE;
284    
285     NICReset();
286    
287     DelayMs(2);
288    
289     SelectBank(0);
290     NICPut(RCR_MSB, SOFT_RST);
291    
292     SelectBank(2);
293     NICPut(MMUCR_LSB, MMU_RESET);
294     /*
295     * MMU_RESET releases all FIFOs. And deallocation may take some time,
296     * so wait until is ready.
297     */
298     do
299     {
300     tempByte.Val = NICGet(MMUCR_LSB);
301     } while( tempByte.bits.b0 );
302    
303     // Disable interrupts.
304     //SelectBank(2);
305     NICPut(MSK, 0x00);
306    
307     SelectBank(1);
308     do
309     {
310     tempByte.Val = NICGet(CTR_LSB);
311     } while( tempByte.bits.b1 );
312    
313     // Ignore bad CRC packets, No auto release transmit buffer
314     NICPut(CTR_MSB, 0b00000000);
315     // No EEPROM, no Store etc.
316     NICPut(CTR_LSB, 0b00000100);
317    
318    
319     // Set MAC Address
320     //SelectBank(1);
321     NICPut(IAR0, MY_MAC_BYTE1);
322     NICPut(IAR1, MY_MAC_BYTE2);
323     NICPut(IAR2, MY_MAC_BYTE3);
324     NICPut(IAR3, MY_MAC_BYTE4);
325     NICPut(IAR4, MY_MAC_BYTE5);
326     NICPut(IAR5, MY_MAC_BYTE6);
327    
328     SelectBank(0);
329    
330     // Enable transmitter, enable automatic pad if packet is less than 64 bytes long
331     NICPut(TCR_LSB, 0b10000001);
332     NICPut(RCR_LSB, 0b00000100); // Accept all multicast packets.
333     NICPut(RCR_MSB, 0b00000001);
334    
335     // Set LEDA and LEDB functionality.
336     NICPut(RPCR_LSB, LEDA_FUNCTION | LEDB_FUNCTION);
337     // Set auto-negotiation mode.
338     NICPut(RPCR_MSB, 0b00001000);
339    
340    
341     // Reset PHY to restart auto-negotiation
342     PHYPut(PHY_CONTROL, 0x8000);
343     // Wait for RESET to complete.
344     do
345     {
346     tempWord.Val = PHYGet(PHY_CONTROL);
347     tempByte.Val = tempWord.byte.MSB;
348     } while( tempByte.bits.b7 );
349    
350    
351     // Advertise...
352     PHYPut(PHY_ANEG_ADV, 0x01e1);
353    
354     // Enable Auto Negotiation and reset at the same time.
355     PHYPut(PHY_CONTROL, 0x3200);
356    
357     // Majority of registers accessed from now-on is in bank 2, so make sure
358     // that bank is set to 2.
359     SelectBank(2);
360    
361     AllocateTxBuffer();
362    
363     }
364    
365    
366     BOOL MACIsTxReady(void)
367     {
368     BYTE_VAL tempByte;
369    
370     SelectBank(0);
371     tempByte.Val = NICGet(EPHSR_LSB);
372     SelectBank(2);
373    
374     return (TxBuffer.flags.bIsFree || tempByte.bits.b0);
375     }
376    
377     BOOL MACIsLinked(void)
378     {
379     return TRUE;
380     }
381    
382    
383    
384     void MACPut(BYTE val)
385     {
386     BYTE_VAL tempByte;
387     BYTE_VAL tempLSB;
388    
389     // Remember LSB so that we can write it as two succesvice writes.
390     tempLSB.Val = NICGet(PTR_LSB);
391    
392     // Tell MMU that we are writing to current FIFO pointer
393     tempByte.Val = NICGet(PTR_MSB);
394     tempByte.bits.b5 = 0;
395     NICPut(PTR_LSB, tempLSB.Val);
396     NICPut(PTR_MSB, tempByte.Val);
397    
398     NICPut(DATA_LSB, val);
399     }
400    
401    
402     void MACPutArray(BYTE *val, WORD len)
403     {
404     while(len--)
405     NICPut(DATA_LSB, *val++);
406    
407     }
408    
409    
410     BYTE MACGet(void)
411     {
412     BYTE_VAL tempByte;
413     BYTE_VAL tempLSB;
414    
415     // Tell MMU that we are reading from current FIFO pointer.
416     // All writes to PTR must be done LSB followed by MSB.
417     tempLSB.Val = NICGet(PTR_LSB);
418     tempByte.Val = NICGet(PTR_MSB);
419     tempByte.bits.b5 = 1;
420     NICPut(PTR_LSB, tempLSB.Val);
421     NICPut(PTR_MSB, tempByte.Val);
422    
423     return NICGet(DATA_LSB);
424     }
425    
426    
427     WORD MACGetArray(BYTE *val, WORD len)
428     {
429     WORD_VAL t;
430    
431     t.Val = len;
432     while (len--)
433     *val++ = NICGet(DATA_LSB);
434    
435     return t.Val;
436     }
437    
438     void MACReserveTxBuffer(BUFFER buffer)
439     {
440     TxBuffer.flags.bIsFree = FALSE;
441     }
442    
443     static BUFFER AllocateTxBuffer(void)
444     {
445     BYTE_VAL tempByte;
446    
447     // All transmit requests results in maximum defined allocation.
448     #define MAC_TX_BUFFER_PAGES (((MAC_TX_BUFFER_SIZE & 0xfffe) + 6)/256)
449    
450     // First of all allocate predefined packet to transmit data.
451     NICPut(MMUCR_LSB, ALLOCATE_TX | (BYTE)MAC_TX_BUFFER_PAGES);
452    
453     // Wait for allocation to complete.
454     do
455     {
456     tempByte.Val = NICGet(IST);
457     } while( !tempByte.bits.b3 );
458    
459     // Read allocated buffer information.
460     tempByte.Val = NICGet(ARR);
461     if ( tempByte.bits.b7 )
462     return INVALID_BUFFER;
463    
464     // Remember current transmit buffer packet number.
465     NICCurrentTxBuffer = tempByte.Val;
466    
467     // Set this as transmit packet.
468     NICPut(PNR, NICCurrentTxBuffer);
469    
470     // Start from begining of packet, AutoIncr etc.
471     // All writes to PTR must be done LSB followed by MSB.
472     NICPut(PTR_LSB, 0);
473     NICPut(PTR_MSB, 0b01000000);
474    
475     return NICCurrentTxBuffer;
476     }
477    
478    
479     void MACDiscardTx(BUFFER buffer)
480     {
481     TxBuffer.flags.bIsFree = TRUE;
482     }
483    
484     void MACDiscardRx(void)
485     {
486     BYTE_VAL tempByte;
487    
488    
489     NICPut(ACK, 0x00);
490    
491     // Discard top of RX FIFO.
492     NICPut(MMUCR_LSB, REMOVE_N_RELEASE_RX);
493    
494    
495     // Wait until release is complete.
496     do
497     {
498     tempByte.Val = NICGet(MMUCR_LSB);
499     } while( tempByte.bits.b0 );
500    
501    
502     }
503    
504    
505     WORD MACGetFreeRxSize(void)
506     {
507     WORD_VAL tempWord;
508     WORD temp;
509    
510     SelectBank(0);
511     // Value returned by NIC is Multiple of 2KB
512     tempWord.byte.LSB = 0;
513     tempWord.byte.MSB = NICGet(MIR_MSB);
514     // Convert it to bytes.
515     tempWord.byte.MSB *= 8;
516     SelectBank(2);
517    
518     temp = tempWord.Val;
519    
520     return tempWord.Val;
521     }
522    
523    
524    
525     BOOL MACGetHeader(MAC_ADDR *remote, BYTE* type)
526     {
527     ETHER_HEADER header;
528     BYTE_VAL tempByte;
529     BYTE temp1, temp2;
530     BYTE tempLSB, tempMSB;
531    
532     *type = MAC_UNKNOWN;
533    
534    
535     // First of all check to see if there is any packet in receive FIFO.
536     tempByte.Val = NICGet(FIFO_MSB);
537     if ( tempByte.bits.b7 )
538     return FALSE;
539    
540    
541    
542     // Remember current packet number.
543     // There should not be need to clear upper 2 bits -
544     // RXEMPTY will always be 0 and so will Reserved bit
545     NICCurrentRdPtr = tempByte.Val;
546    
547     // Now mark that we are reading RX FIFO and set AUTOINCR.
548     // All writes to PTR must be done LSB followed by MSB.
549     NICPut(PTR_LSB, 0);
550     NICPut(PTR_MSB, 0b11100000); // RCV, AUTOINCR, READ.
551    
552     // Read Status - only interested in MSB; discard LSB
553     temp2 = NICGet(DATA_LSB);
554     tempByte.Val = NICGet(DATA_LSB);
555    
556     // Overrun packet would autoamtically be aborted by MMU, so we don't have
557     // to worry about it (?)
558    
559     // Fetch and discard byte count of this packet.
560     tempLSB = NICGet(DATA_LSB);
561     tempMSB = NICGet(DATA_LSB);
562    
563     // Process it only if there is no error.
564     temp1 = tempByte.Val;
565     if ( tempByte.Val & 0b10101000 )
566     goto MACGetHeaderDiscard;
567    
568     // Now starts the actual ethernet packet. Read entire header
569     MACGetArray((BYTE*)&header, sizeof(header));
570    
571    
572     header.Type.Val = swaps(header.Type.Val);
573    
574     memcpy((void*)remote->v, (void*)header.SourceMACAddr.v, sizeof(*remote));
575    
576     if ( (header.Type.v[1] == 0x08) && ((header.Type.v[0] == ETHER_IP) || (header.Type.v[0] == ETHER_ARP)) )
577     *type = header.Type.v[0];
578    
579    
580     return TRUE;
581    
582     MACGetHeaderDiscard:
583     MACDiscardRx();
584     return FALSE;
585    
586     }
587    
588    
589    
590     void MACPutHeader(MAC_ADDR *remote,
591     BYTE type,
592     WORD dataLen)
593     {
594     WORD_VAL tempWord;
595     BYTE_VAL tempByte;
596     WORD temp1;
597     BYTE etherType;
598    
599    
600     // Remember length of this packet so that we can write last control byte
601     // at correct offset.
602     TxBuffer.length.Val = dataLen + (WORD)sizeof(ETHER_HEADER);
603    
604     // Start from begining of packet, AutoIncr etc.
605     // All writes to PTR must be done LSB followed by MSB.
606     NICPut(PTR_LSB, 0);
607     NICPut(PTR_MSB, 0b01000000);
608    
609     // Stuff initial housekeeping info.
610     // Status word of all 0's
611     NICPut(DATA_LSB, 0);
612     NICPut(DATA_LSB, 0);
613    
614     // Byte count - In words only.
615     tempWord.Val = TxBuffer.length.Val;
616     tempWord.Val += 6; // Include status, byte count, and control words
617     temp1 = tempWord.Val;
618     NICPut(DATA_LSB, tempWord.byte.LSB);
619     NICPut(DATA_LSB, tempWord.byte.MSB);
620    
621     MACPutArray((BYTE*)remote, sizeof(*remote));
622    
623     MACPut(MY_MAC_BYTE1);
624     MACPut(MY_MAC_BYTE2);
625     MACPut(MY_MAC_BYTE3);
626     MACPut(MY_MAC_BYTE4);
627     MACPut(MY_MAC_BYTE5);
628     MACPut(MY_MAC_BYTE6);
629    
630     if ( type == MAC_IP )
631     etherType = ETHER_IP;
632     else
633     etherType = ETHER_ARP;
634    
635     MACPut(0x08);
636     MACPut(etherType);
637    
638     }
639    
640     void MACFlush(void)
641     {
642     // Set TXFIFO pointer to point to end of current tx buffer.
643     TxBuffer.length.Val += 4; // Account for status word and byte count word.
644    
645     // All writes to PTR must be done LSB followed by MSB.
646     NICPut(PTR_LSB, TxBuffer.length.byte.LSB);
647     NICPut(PTR_MSB, 0b01000000 | TxBuffer.length.byte.MSB);
648    
649     // Write control byte and extra byte if total buffer length is odd.
650     if ( TxBuffer.length.byte.LSB & 0x01 )
651     NICPut(DATA_LSB, 0b00100000); // Control byte - ODD count
652     else
653     {
654     NICPut(DATA_LSB, 0); // Extra byte - will not be transmitted
655     NICPut(DATA_LSB, 0); // Control byte - even count
656     }
657    
658     NICPut(PNR, NICCurrentTxBuffer);
659     NICPut(MMUCR_LSB, ENQUE_TX_PACKET);
660     NICPut(MMUCR_MSB, 0);
661    
662     // If we don't have to preserve this packet, wait for it to get
663     // transmitted and then release it.
664     if ( !TxBuffer.flags.bIsFree )
665     TxBuffer.flags.bIsFree = TRUE;
666    
667     }
668    
669     static void NICReset(void)
670     {
671     SET_NIC_READ();
672     WRITE_NIC_ADDR(0);
673     INTCON2_RBPU = 0;
674    
675     NIC_IOW_IO = 1;
676     NIC_IOR_IO = 1;
677     NIC_RESET_IO = 1;
678     NIC_CTRL_TRIS = 0x00;
679    
680     // Reset pulse must be at least 800 ns.
681     Delay10us(1);
682    
683     NIC_RESET_IO = 0;
684     }
685    
686     static void NICPut(BYTE reg, BYTE val)
687     {
688     WRITE_NIC_ADDR(reg);
689     NIC_DATA_IO = val;
690     SET_NIC_WRITE();
691     NIC_IOW_IO = 0;
692     NIC_IOW_IO = 1;
693     SET_NIC_READ();
694     }
695    
696     static BYTE NICGet(BYTE reg)
697     {
698     BYTE val;
699    
700     SET_NIC_READ();
701     WRITE_NIC_ADDR(reg);
702     NIC_IOR_IO = 0;
703     val = NIC_DATA_IO;
704     NIC_IOR_IO = 1;
705     return val;
706     }
707    
708    
709     void MACSetRxBuffer(WORD offset)
710     {
711     WORD_VAL tempWord;
712     BYTE_VAL tempByte;
713    
714     // Set current packet to current Receive packet number.
715    
716     tempWord.byte.MSB = 0;
717     tempWord.byte.LSB = sizeof(ETHER_HEADER)+4;
718     tempWord.Val += offset;
719    
720     tempByte.Val = tempWord.byte.LSB & 0x03;
721     tempWord.byte.LSB &= 0xfc;
722    
723     NICPut(PTR_LSB, tempWord.byte.LSB);
724     NICPut(PTR_MSB, 0b11100000 | tempWord.byte.MSB);
725    
726     // Fetch and discard un-aligned data bytes.
727     while( tempByte.Val-- )
728     NICGet(DATA_LSB);
729     }
730    
731     void MACSetTxBuffer(BUFFER buffer, WORD offset)
732     {
733     WORD_VAL tempWord;
734    
735     // Make given packet as one that is accessible.
736     NICPut(PNR, buffer);
737    
738     tempWord.byte.MSB = 0;
739     // Account for 4 bytes of status word and byte count word.
740     tempWord.byte.LSB = sizeof(ETHER_HEADER)+4;
741     tempWord.Val += offset;
742    
743     NICPut(PTR_LSB, tempWord.byte.LSB);
744     NICPut(PTR_MSB, 0b01000000 | tempWord.byte.MSB);
745     }
746    
747     WORD MACGetOffset(void)
748     {
749     WORD_VAL tempWord;
750    
751     tempWord.byte.MSB = NICGet(PTR_MSB);
752     tempWord.byte.MSB &= 0b00000111;
753    
754     tempWord.byte.LSB = NICGet(PTR_LSB);
755    
756     return tempWord.Val;
757     }
758    
759     static void WriteNICAddr(BYTE addr)
760     {
761     BYTE_VAL tAddr;
762    
763     tAddr.Val = addr;
764    
765     UB(tAddr) = !LB(tAddr);
766     NIC_ADDR_IO = tAddr.Val;
767     TRISB = 0xe0;
768     }
769    
770    
771    
772    
773     static WORD PHYGet(BYTE addr)
774     {
775     WORD_VAL tempWord;
776    
777     MIIBeginCommand(MII_CMD_READ, addr);
778    
779     tempWord.byte.MSB = MIIGet(addr);
780     tempWord.byte.LSB = MIIGet(addr);
781    
782     NICPut(MGMT_LSB, MII_MCLK_LOW);
783     NICPut(MGMT_LSB, MII_MCLK_HIGH);
784    
785     return tempWord.Val;
786     }
787    
788     static void PHYPut(BYTE addr, WORD val)
789     {
790     WORD_VAL tempWord;
791    
792     MIIBeginCommand(MII_CMD_WRITE, addr);
793    
794     tempWord.Val = val;
795    
796     MIIPut(tempWord.byte.MSB, 8);
797     MIIPut(tempWord.byte.LSB, 8);
798    
799     NICPut(MGMT_LSB, 0);
800    
801     }
802    
803     static void MIIBeginCommand(BYTE command, BYTE reg)
804     {
805     BYTE i;
806    
807     SelectBank(3);
808    
809     // 32 '1's to synchronize MII
810     for ( i = 0; i < 32; i++ )
811     {
812     NICPut(MGMT_LSB, MII_MDOE_HIGH | MII_MCLK_LOW | MII_MDO_HIGH);
813     DelayMs(1);
814     NICPut(MGMT_LSB, MII_MDOE_HIGH | MII_MCLK_HIGH | MII_MDO_HIGH);
815     }
816    
817     DelayMs(1);
818     MIIPut(command, 8); // Start(01), Read(10), PhyAdr<4:1)=0000
819    
820     // Put PhyAdr<0>, REGAD<4:0>, TA<1:0>
821     if ( command == MII_CMD_READ )
822     {
823     MIIPut(reg, 6);
824    
825     // One Z-bit of turnaround time.
826     NICPut(MGMT_LSB, MII_MCLK_LOW );
827     NICPut(MGMT_LSB, MII_MCLK_HIGH);
828    
829     }
830     else
831     MIIPut(reg, 8);
832     }
833    
834     static BYTE MIIGet(BYTE data)
835     {
836     BYTE_VAL temp;
837     BYTE_VAL tempVal;
838     BYTE i;
839    
840    
841     for ( i = 0; i < 8; i++ )
842     {
843     temp.Val = NICGet(MGMT_LSB);
844     if ( temp.bits.b1 )
845     tempVal.bits.b0 = 1;
846     else
847     tempVal.bits.b0 = 0;
848    
849     NICPut(MGMT_LSB, MII_MDOE_LOW | MII_MCLK_LOW);
850     DelayMs(1);
851     NICPut(MGMT_LSB, MII_MDOE_LOW | MII_MCLK_HIGH);
852     DelayMs(1);
853    
854     tempVal.Val <<= 1;
855     }
856     return tempVal.Val;
857     }
858    
859     static void MIIPut(BYTE data, BYTE bitCount)
860     {
861     BYTE_VAL temp;
862     BYTE i;
863    
864    
865     temp.Val = data;
866     for ( i = 0; i < bitCount; i++ )
867     {
868     if ( temp.bits.b7 )
869     {
870     NICPut(MGMT_LSB, MII_MDOE_HIGH | MII_MCLK_LOW | MII_MDO_HIGH);
871     DelayMs(1);
872     NICPut(MGMT_LSB, MII_MDOE_HIGH | MII_MCLK_HIGH | MII_MDO_HIGH);
873     }
874     else
875     {
876     NICPut(MGMT_LSB, MII_MDOE_HIGH | MII_MCLK_LOW | MII_MDO_LOW);
877     DelayMs(1);
878     NICPut(MGMT_LSB, MII_MDOE_HIGH | MII_MCLK_HIGH | MII_MDO_LOW);
879     }
880     DelayMs(1);
881    
882     temp.Val <<= 1;
883     }
884     }

  ViewVC Help
Powered by ViewVC 1.1.20