📄 ethernet.lst
字号:
C51 COMPILER V7.50 ETHERNET 12/23/2005 11:15:15 PAGE 1
C51 COMPILER V7.50, COMPILATION OF MODULE ETHERNET
OBJECT MODULE PLACED IN ethernet.OBJ
COMPILER INVOKED BY: d:\Keil\C51\BIN\C51.EXE ethernet.c LARGE OPTIMIZE(SIZE) BROWSE DEBUG OBJECTEXTEND
line level source
1 #include <reg52.h>
2 #include <absacc.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include "reg_ne2k.h"
6 #include "ethernet.h"
7 sbit HW_RESET=0xb4;
8 BYTE mymac[MACLEN];
9 typedef struct { /* NIC hardware packet header */
10 BYTE stat; /* Error status */
11 BYTE next; /* Pointer to next block */
12 WORD len; /* Length of this frame incl. CRC */
13 } NICHDR;
14 NICHDR nichdr;
15
16 void delay_ms(int number);
17 void resetnic();
18 void getnic(WORD addr,BYTE buf[],WORD len);
19 void putnic(WORD addr,BYTE buf[],WORD len);
20 BYTE nicwrap(BYTE page);
21
22 //***************************************************
23 // 接收数据包,将8019中的数据包读入指定的数据包缓冲区pkt,帧头读入nichdr结构中
24 // 全局变量 nichdr
25 // 全局变量 next_packet
26 // 返回:如果接收到数据包,返回数据包长度len,(该长度为减去校验和长度)
27 // 否则 : 0
28 // get packet into buffer,return length (excel CRC ),or 0 if no available
29 //***************************************************
30 WORD get_ethernet(void *efp)
31 {
32 1 WORD current_offset;
33 1 BYTE curr_page;
34 1 BYTE bnry;
35 1 if (EN0_ISR &0x10) resetnic();
36 1 /* Get the Receive Page, CURR */
37 1 EN_CMD = EN_NODMA + EN_PAGE1 + EN_START;
38 1 curr_page = EN1_CURPAG;
39 1 EN_CMD = EN_NODMA + EN_PAGE0 + EN_START;
40 1 bnry=EN0_BOUNDARY+1; /* Get the BOUNDARY Register */
41 1 if (bnry>RX_STOP_PG) bnry=RX_START_PG;
42 1 /* Remove one frame from the ring. Boundary is always a page behind. */
43 1 // if (curr_page==0) return (0);
44 1 if (bnry!=curr_page)
45 1 {
46 2 current_offset = (WORD)(bnry << 8);
47 2 /* Get the header of this packet */
48 2 memset(&nichdr,0xee,sizeof(nichdr));
49 2 getnic(current_offset, (BYTE *)&nichdr,sizeof(nichdr));
50 2 nichdr.len=(nichdr.len/256)+((nichdr.len %256)<<8);
51 2 //keil c 在结构中使用该方法时,编译器编译的不正确(keil c bug)
52 2 // nichdr.len=(nichdr.len>>8)&0xff+(nichdr.len&0xff)<<8;
53 2 if ((nichdr.stat &0x01) && nichdr.len>=MINFRAMEC && nichdr.len<=MAXFRAMEC)
54 2 getnic(current_offset+sizeof(nichdr),(BYTE *)efp,nichdr.len-sizeof(nichdr));
55 2 if (nichdr.next>=RX_START_PG && nichdr.next<RX_STOP_PG)
C51 COMPILER V7.50 ETHERNET 12/23/2005 11:15:15 PAGE 2
56 2 bnry=nichdr.next;
57 2 else
58 2 bnry=nicwrap(bnry+1); //nic error
59 2 bnry=nicwrap(bnry-1);
60 2 EN0_BOUNDARY=bnry;
61 2 return (nichdr.len-sizeof(nichdr)-sizeof(ETHERHDR));
62 2 }
63 1 return (0);
64 1 }
65 //*************************************************************
66 // Send Ethernet packet give Len excl. CRC,return 0 if NIC busy
67 // 全局变量 locnode.mac (本地的以太物理地址 )
68 //
69 //*************************************************************
70 WORD put_ethernet(void *efp,WORD len)
71 {
72 1 if (EN_CMD & EN_TRANS) /* if still TXing,return 0 */
73 1 len=0;
74 1 else
75 1 {
76 2 len=min(MAXFRAME,max(len,MINFRAME));
77 2 EN_CMD=EN_PAGE0+EN_NODMA;
78 2 EN0_ISR=EN_RREAD+EN_START;
79 2 EN0_TCNTLO=(BYTE)(len & 0xff);
80 2 EN0_TCNTHI=(BYTE)(len>>8);
81 2 putnic(TX_START_PG<<8,(BYTE *)efp,len);
82 2 EN_CMD=EN_NODMA+EN_PAGE0+EN_TRANS;
83 2 }
84 1 return(len);
85 1 }
86 //*************************************************************
87 // reset nic (ne2000 compact 8019as)
88 //*************************************************************
89 void resetnic()
90 {
91 1 HW_RESET = 1; /* Hardware RESET. when EN_RESET = 0; is Software */
92 1 delay_ms(10);
93 1 HW_RESET = 0;
94 1 delay_ms(10);
95 1
96 1 EN_CMD = EN_PAGE0 + EN_NODMA + EN_STOP; /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */
97 1 delay_ms(4);
98 1 // EN0_DCFG = ENDCFG_FT10 + ENDCFG_BMS + ENDCFG_BOS; /* ?FIFO treshold 8byte !!,normal operation, by
-te transfer mode selection */
99 1 /* Clear the remote byte count registers. */
100 1 EN0_DCFG = ENDCFG_FT10 + ENDCFG_BMS;
101 1 EN0_RCNTHI = 0x00; /* MSB remote byte count reg */
102 1 EN0_RCNTLO = 0x00; /* LSB remote byte count reg */
103 1
104 1 EN0_RXCR = E8390_RXOFF; /* RX configuration reg Monitor mode (no packet receive) */
105 1 EN0_TXCR = E8390_TXOFF; /* TX configuration reg set internal loopback mode */
106 1
107 1 EN0_TPSR = NE_START_PG;
108 1 EN0_STARTPG = RX_START_PG ; /* DMA START PAGE 46h */
109 1 /* Starting page of ring buffer. First page of Rx ring buffer 46h*/
110 1 EN0_STOPPG = NE_STOP_PG; /* Ending page +1 of ring buffer */
111 1 EN0_BOUNDARY = RX_START_PG; /* Boundary page of ring buffer */
112 1 EN0_ISR = 0xff; /* INTerrupt stauts reg */
113 1 EN0_IMR = 0; /* INTerrupt mask reg = Disable all Interrupt */
114 1
115 1
116 1 EN_CMD = EN_PAGE1 + EN_NODMA+EN_STOP;
C51 COMPILER V7.50 ETHERNET 12/23/2005 11:15:15 PAGE 3
117 1 delay_ms(4);
118 1 EN1_PAR0 = mymac[0];
119 1 EN1_PAR1 = mymac[1];
120 1 EN1_PAR2 = mymac[2];
121 1 EN1_PAR3 = mymac[3];
122 1 EN1_PAR4 = mymac[4];
123 1 EN1_PAR5 = mymac[5];
124 1 /* Initialize the multicast list to accept-all. If we enable multicast
125 1 the higher levels can do the filtering. multicast filter mask array (8 bytes) */
126 1 EN1_MAR0 = 0xff;
127 1 EN1_MAR1 = 0xff;
128 1 EN1_MAR2 = 0xff;
129 1 EN1_MAR3 = 0xff;
130 1 EN1_MAR4 = 0xff;
131 1 EN1_MAR5 = 0xff;
132 1 EN1_MAR6 = 0xff;
133 1 EN1_MAR7 = 0xff;
134 1
135 1 EN1_CURR = RX_START_PG + 1; /* RX_CURR_PG; Current memory page = RX_CURR_PG ? */
136 1
137 1 EN_CMD = EN_PAGE0 + EN_NODMA ; /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */
138 1
139 1 EN0_RXCR = ENRXCR_RXCONFIG; /* rx on(broadcasts, no multicast,errors 04*/
140 1 EN0_TXCR = ENTXCR_TXCONFIG; /* xmit on. */
141 1
142 1 EN0_ISR = 0xff; /* Individual bits are cleared by writing a "1" into it. */
143 1 /* It must be cleared after power up. */
144 1
145 1 EN0_IMR = ENISR_ALL; /* INTerrupt mask reg */
146 1
147 1 EN_CMD = EN_PAGE0 + EN_NODMA + EN_START;
148 1 }
149 //*******************************************
150 // get a packet form a given address in NIC's RAM
151 // DMA READ
152 //
153 //*******************************************
154 void getnic(WORD addr, BYTE buf[],WORD len)
155 {
156 1 EN0_ISR=ENISR_RDC; //clear remote dma interrupt flag
157 1 EN0_RCNTLO = (BYTE)(len&0xff); // read length low
158 1 EN0_RCNTHI = (BYTE)(len>>8); // read length high
159 1 EN0_RSARLO=(BYTE)(addr &0xff); // read address low
160 1 EN0_RSARHI=(BYTE)(addr>>8); // read address high
161 1 EN_CMD=EN_RREAD+EN_START+EN_PAGE0; // do dma read
162 1 while (len--)
163 1 *buf++=EN_DATA;
164 1 }
165
166 //*******************************************
167 // put a packet into a given address in NIC's RAM
168 // DMA Write
169 //
170 //*******************************************
171 void putnic(WORD addr, BYTE buf[],WORD len)
172 {
173 1 len+=len&0x01;
174 1 EN0_ISR=ENISR_RDC; //clear remote dma interrupt flag
175 1 EN0_RCNTLO = (BYTE)(len&0xff);
176 1 EN0_RCNTHI = (BYTE)(len>>8);
177 1 EN0_RSARLO=(BYTE)(addr &0xff);
178 1 EN0_RSARHI=(BYTE)(addr>>8);
C51 COMPILER V7.50 ETHERNET 12/23/2005 11:15:15 PAGE 4
179 1 EN_CMD=EN_RWRITE+EN_START+EN_PAGE0;
180 1 while (len--)
181 1 EN_DATA=*buf++;
182 1 len=10000;
183 1 while ((len && (EN0_ISR & ENISR_RDC))==0)
184 1 len--;
185 1 }
186 //***************************************
187 // wrap an rx page number
188 //***************************************
189 BYTE nicwrap(BYTE page)
190 {
191 1 if (page>=RX_STOP_PG)
192 1 page+=RX_START_PG-RX_STOP_PG;
193 1 else if(page<RX_START_PG)
194 1 page+=RX_STOP_PG-RX_START_PG;
195 1 return (page);
196 1 }
197
198 //*********************************************************************
199 // 延时子程序 1ms
200 //*********************************************************************
201 void delay_ms(int number)
202 { //craystal 22.1184Mhz
203 1 unsigned char i;
204 1 unsigned int j;
205 1 for (j=0;j<number;j++)
206 1 {
207 2 for (i=0;i<229;i++); //11.0592Mhz (1ms)
208 2 for (i=0;i<229;i++); //22.1184Mhz (1ms)
209 2 }
210 1 }
211 //*********************************************************************
212 // 延时子程序 100ms
213 //*********************************************************************
214
215 //void delay_100ms(int number)
216 //{
217 // unsigned int j;
218 // for (j=0;j<number;j++)
219 // delay_ms(100);
220 //}
221
222 /* Make a frame, given data length. Return length of complete frame
223 ** If Ethernet, set dest addr & protocol type; if SLIP, ignore these */
224 int make_frame(ETHERFRAME *efp, BYTE srce[],BYTE dest[], WORD pcol, WORD dlen)
225 {
226 1
227 1 efp->e.ptype = pcol;
228 1 memcpy(efp->e.dest, dest, MACLEN);
229 1 memcpy(efp->e.srce, srce, MACLEN);
230 1 dlen += sizeof(ETHERHDR);
231 1 return(dlen);
232 1 }
233
234
235 /* Do TCP-style checksum. Improved algorithm is from RFC 1071 */
236 WORD csum(void *dp, WORD count)
237 {
238 1 register LWORD total=0L;
239 1 register WORD n, *p, carries;
240 1
C51 COMPILER V7.50 ETHERNET 12/23/2005 11:15:15 PAGE 5
241 1 n = count / 2;
242 1 p = (WORD *)dp;
243 1 while (n--)
244 1 total += *p++;
245 1 if (count & 1)
246 1 total += (*(BYTE *)p)<<8;
247 1 while ((carries=(WORD)(total>>16))!=0)
248 1 total = (total & 0xffffL) + carries;
249 1 return((WORD)total);
250 1 }
251
252
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1262 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = 10 48
PDATA SIZE = ---- ----
DATA SIZE = ---- ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -