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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (show annotations) (download)
Tue May 1 08:17:39 2007 UTC (17 years, 1 month 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 /*********************************************************************
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