Line No. | Rev | Author | Line |
---|---|---|---|
1 | 6 | kaklik | /*! \file ax88796.c \brief ASIX AX88796 Ethernet Interface Driver. */ |
2 | //***************************************************************************** |
||
3 | // |
||
4 | // File Name : 'ax88796.c' |
||
5 | // Title : ASIX AX88796 Ethernet Interface Driver |
||
6 | // Author : Pascal Stang |
||
7 | // Created : 10/22/2002 |
||
8 | // Revised : 8/21/2005 |
||
9 | // Version : 0.1 |
||
10 | // Target MCU : Atmel AVR series |
||
11 | // Editor Tabs : 4 |
||
12 | // |
||
13 | // Description : This driver provides initialization and transmit/receive |
||
14 | // functions for the ASIX AX88796 10/100Mb Ethernet Controller and PHY. |
||
15 | // |
||
16 | // Based in part on code by Louis Beaudoin (www.embedded-creations.com). |
||
17 | // Thanks to Adam Dunkels and Louis Beaudoin for providing the initial |
||
18 | // structure in which to write this driver. |
||
19 | // |
||
20 | //***************************************************************************** |
||
21 | |||
22 | #include "global.h" |
||
23 | #include "timer.h" |
||
24 | #include "rprintf.h" |
||
25 | |||
26 | #include "ax88796.h" |
||
27 | |||
28 | // include configuration |
||
29 | #include "ax88796conf.h" |
||
30 | |||
31 | // pointers to locations in the ax88796 receive buffer |
||
32 | static unsigned char NextPage; // page pointer to next Rx packet |
||
33 | static unsigned int CurrentRetreiveAddress; // DMA address for read Rx packet location |
||
34 | |||
35 | |||
36 | void nicInit(void) |
||
37 | { |
||
38 | ax88796Init(); |
||
39 | } |
||
40 | |||
41 | void nicSend(unsigned int len, unsigned char* packet) |
||
42 | { |
||
43 | ax88796BeginPacketSend(len); |
||
44 | ax88796SendPacketData(packet, len); |
||
45 | ax88796EndPacketSend(); |
||
46 | } |
||
47 | |||
48 | unsigned int nicPoll(unsigned int maxlen, unsigned char* packet) |
||
49 | { |
||
50 | unsigned int packetLength; |
||
51 | |||
52 | packetLength = ax88796BeginPacketRetreive(); |
||
53 | |||
54 | // if there's no packet or an error - exit without ending the operation |
||
55 | if( !packetLength ) |
||
56 | return 0; |
||
57 | |||
58 | // drop anything too big for the buffer |
||
59 | if( packetLength > maxlen ) |
||
60 | { |
||
61 | ax88796EndPacketRetreive(); |
||
62 | return 0; |
||
63 | } |
||
64 | |||
65 | // copy the packet data into the uIP packet buffer |
||
66 | ax88796RetreivePacketData( packet, packetLength ); |
||
67 | ax88796EndPacketRetreive(); |
||
68 | |||
69 | return packetLength; |
||
70 | } |
||
71 | |||
72 | void nicGetMacAddress(u08* macaddr) |
||
73 | { |
||
74 | u08 tempCR; |
||
75 | // switch register pages |
||
76 | tempCR = ax88796Read(CR); |
||
77 | ax88796Write(CR,tempCR|PS0); |
||
78 | // read MAC address registers |
||
79 | *macaddr++ = ax88796Read(PAR0); |
||
80 | *macaddr++ = ax88796Read(PAR1); |
||
81 | *macaddr++ = ax88796Read(PAR2); |
||
82 | *macaddr++ = ax88796Read(PAR3); |
||
83 | *macaddr++ = ax88796Read(PAR4); |
||
84 | *macaddr++ = ax88796Read(PAR5); |
||
85 | // switch register pages back |
||
86 | ax88796Write(CR,tempCR); |
||
87 | } |
||
88 | |||
89 | void nicSetMacAddress(u08* macaddr) |
||
90 | { |
||
91 | u08 tempCR; |
||
92 | // switch register pages |
||
93 | tempCR = ax88796Read(CR); |
||
94 | ax88796Write(CR,tempCR|PS0); |
||
95 | // write MAC address registers |
||
96 | ax88796Write(PAR0, *macaddr++); |
||
97 | ax88796Write(PAR1, *macaddr++); |
||
98 | ax88796Write(PAR2, *macaddr++); |
||
99 | ax88796Write(PAR3, *macaddr++); |
||
100 | ax88796Write(PAR4, *macaddr++); |
||
101 | ax88796Write(PAR5, *macaddr++); |
||
102 | // switch register pages back |
||
103 | ax88796Write(CR,tempCR); |
||
104 | } |
||
105 | |||
106 | void nicRegDump(void) |
||
107 | { |
||
108 | ax88796RegDump(); |
||
109 | } |
||
110 | |||
111 | |||
112 | void ax88796SetupPorts(void) |
||
113 | { |
||
114 | #if NIC_CONNECTION == MEMORY_MAPPED |
||
115 | // enable external SRAM interface - no wait states |
||
116 | sbi(MCUCR, SRE); |
||
117 | // sbi(MCUCR, SRW10); |
||
118 | // sbi(XMCRA, SRW00); |
||
119 | // sbi(XMCRA, SRW01); |
||
120 | // sbi(XMCRA, SRW11); |
||
121 | #else |
||
122 | // set address port to output |
||
123 | AX88796_ADDRESS_DDR = AX88796_ADDRESS_MASK; |
||
124 | |||
125 | // set data port to input with pull-ups |
||
126 | AX88796_DATA_DDR = 0x00; |
||
127 | AX88796_DATA_PORT = 0xFF; |
||
128 | |||
129 | // initialize the control port read and write pins to de-asserted |
||
130 | sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN ); |
||
131 | sbi( AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN ); |
||
132 | // set the read and write pins to output |
||
133 | sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_READPIN ); |
||
134 | sbi( AX88796_CONTROL_DDR, AX88796_CONTROL_WRITEPIN ); |
||
135 | #endif |
||
136 | // set reset pin to output |
||
137 | sbi( AX88796_RESET_DDR, AX88796_RESET_PIN ); |
||
138 | } |
||
139 | |||
140 | |||
141 | #if NIC_CONNECTION == MEMORY_MAPPED |
||
142 | inline void ax88796Write(u08 address, u08 data) |
||
143 | { |
||
144 | *(volatile u08*)(AX88796_MEMORY_MAPPED_OFFSET + address) = data; |
||
145 | } |
||
146 | #else |
||
147 | void ax88796Write(u08 address, u08 data) |
||
148 | { |
||
149 | // assert the address |
||
150 | AX88796_ADDRESS_PORT = address | (AX88796_ADDRESS_PORT&~AX88796_ADDRESS_MASK); |
||
151 | |||
152 | // set data bus as output and place data on bus |
||
153 | AX88796_DATA_DDR = 0xFF; |
||
154 | AX88796_DATA_PORT = data; |
||
155 | |||
156 | // clock write pin |
||
157 | cbi(AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN); |
||
158 | nop(); |
||
159 | nop(); |
||
160 | sbi(AX88796_CONTROL_PORT, AX88796_CONTROL_WRITEPIN); |
||
161 | |||
162 | // set data bus back to input with pullups enabled |
||
163 | AX88796_DATA_DDR = 0x00; |
||
164 | AX88796_DATA_PORT = 0xFF; |
||
165 | } |
||
166 | #endif |
||
167 | |||
168 | |||
169 | #if NIC_CONNECTION == MEMORY_MAPPED |
||
170 | inline u08 ax88796Read(u08 address) |
||
171 | { |
||
172 | return *(volatile u08*)(AX88796_MEMORY_MAPPED_OFFSET + address); |
||
173 | } |
||
174 | #else |
||
175 | u08 ax88796Read(u08 address) |
||
176 | { |
||
177 | u08 data; |
||
178 | |||
179 | // assert the address |
||
180 | AX88796_ADDRESS_PORT = address | (AX88796_ADDRESS_PORT&~AX88796_ADDRESS_MASK); |
||
181 | |||
182 | // assert read |
||
183 | cbi(AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN); |
||
184 | nop(); |
||
185 | nop(); |
||
186 | // read in the data |
||
187 | data = AX88796_DATA_PIN; |
||
188 | |||
189 | // negate read |
||
190 | sbi(AX88796_CONTROL_PORT, AX88796_CONTROL_READPIN); |
||
191 | |||
192 | return data; |
||
193 | } |
||
194 | #endif |
||
195 | |||
196 | |||
197 | void ax88796Init(void) |
||
198 | { |
||
199 | unsigned char tcrFduFlag; |
||
200 | |||
201 | // initialize I/O ports |
||
202 | ax88796SetupPorts(); |
||
203 | |||
204 | // do a hard reset |
||
205 | sbi(AX88796_RESET_PORT, AX88796_RESET_PIN); |
||
206 | delay_ms(100); |
||
207 | cbi(AX88796_RESET_PORT, AX88796_RESET_PIN); |
||
208 | |||
209 | // do soft reset |
||
210 | ax88796Write(ISR, ax88796Read(ISR)); |
||
211 | delay_ms(50); |
||
212 | |||
213 | // wait for PHY to come out of reset |
||
214 | ax88796Read(RSTPORT); |
||
215 | while(ax88796Read(TR) & RST_B); |
||
216 | |||
217 | ax88796WriteMii(0x10,0x00,0x0800); |
||
218 | delay_ms(255); |
||
219 | ax88796WriteMii(0x10,0x00,0x1200); |
||
220 | |||
221 | ax88796Write(CR,(RD2|STOP)); // stop the NIC, abort DMA, page 0 |
||
222 | delay_ms(5); // make sure nothing is coming in or going out |
||
223 | ax88796Write(DCR,DCR_INIT); |
||
224 | ax88796Write(RBCR0,0x00); |
||
225 | ax88796Write(RBCR1,0x00); |
||
226 | ax88796Write(IMR,0x00); |
||
227 | ax88796Write(ISR,0xFF); |
||
228 | ax88796Write(RCR,0x20); |
||
229 | ax88796Write(BNRY,RXSTART_INIT); |
||
230 | ax88796Write(PSTART,RXSTART_INIT); |
||
231 | ax88796Write(PSTOP,RXSTOP_INIT); |
||
232 | |||
233 | // switch to page 1 |
||
234 | ax88796Write(CR,(PS0|RD2|STOP)); |
||
235 | // write mac address |
||
236 | ax88796Write(PAR0+0, AX88796_MAC0); |
||
237 | ax88796Write(PAR0+1, AX88796_MAC1); |
||
238 | ax88796Write(PAR0+2, AX88796_MAC2); |
||
239 | ax88796Write(PAR0+3, AX88796_MAC3); |
||
240 | ax88796Write(PAR0+4, AX88796_MAC4); |
||
241 | ax88796Write(PAR0+5, AX88796_MAC5); |
||
242 | // set start point |
||
243 | ax88796Write(CURR,RXSTART_INIT+1); |
||
244 | |||
245 | ax88796Write(CR,(RD2|START)); |
||
246 | ax88796Write(RCR,RCR_INIT); |
||
247 | |||
248 | if(ax88796Read(GPI) & I_SPD) // check PHY speed setting |
||
249 | tcrFduFlag = FDU; // if 100base, do full duplex |
||
250 | else |
||
251 | tcrFduFlag = 0; // if 10base, do half duplex |
||
252 | |||
253 | ax88796Write(TCR,(tcrFduFlag|TCR_INIT)); |
||
254 | |||
255 | ax88796Write(GPOC,MPSEL); // select media interface |
||
256 | |||
257 | ax88796Write(TPSR,TXSTART_INIT); |
||
258 | |||
259 | ax88796Write(CR,(RD2|STOP)); |
||
260 | ax88796Write(DCR,DCR_INIT); |
||
261 | ax88796Write(CR,(RD2|START)); |
||
262 | ax88796Write(ISR,0xFF); |
||
263 | ax88796Write(IMR,IMR_INIT); |
||
264 | ax88796Write(TCR,(tcrFduFlag|TCR_INIT)); |
||
265 | |||
266 | //test |
||
267 | /* |
||
268 | while(1) |
||
269 | { |
||
270 | vt100SetCursorPos(18,0); |
||
271 | ax88796RegDump(); |
||
272 | } |
||
273 | */ |
||
274 | } |
||
275 | |||
276 | |||
277 | void ax88796BeginPacketSend(unsigned int packetLength) |
||
278 | { |
||
279 | unsigned int sendPacketLength; |
||
280 | sendPacketLength = (packetLength>=ETHERNET_MIN_PACKET_LENGTH)? |
||
281 | (packetLength):(ETHERNET_MIN_PACKET_LENGTH); |
||
282 | |||
283 | //start the NIC |
||
284 | ax88796Write(CR,(RD2|START)); |
||
285 | |||
286 | // still transmitting a packet - wait for it to finish |
||
287 | while( ax88796Read(CR) & TXP ); |
||
288 | |||
289 | //load beginning page for transmit buffer |
||
290 | ax88796Write(TPSR,TXSTART_INIT); |
||
291 | |||
292 | //set start address for remote DMA operation |
||
293 | ax88796Write(RSAR0,0x00); |
||
294 | ax88796Write(RSAR1,0x40); |
||
295 | |||
296 | //clear the packet stored interrupt |
||
297 | ax88796Write(ISR, PTX); |
||
298 | |||
299 | //load data byte count for remote DMA |
||
300 | ax88796Write(RBCR0, (unsigned char)(packetLength)); |
||
301 | ax88796Write(RBCR1, (unsigned char)(packetLength>>8)); |
||
302 | |||
303 | ax88796Write(TBCR0, (unsigned char)(sendPacketLength)); |
||
304 | ax88796Write(TBCR1, (unsigned char)((sendPacketLength)>>8)); |
||
305 | |||
306 | //do remote write operation |
||
307 | ax88796Write(CR,0x12); |
||
308 | } |
||
309 | |||
310 | |||
311 | void ax88796SendPacketData(unsigned char * localBuffer, unsigned int length) |
||
312 | { |
||
313 | unsigned int i; |
||
314 | |||
315 | for(i=0;i<length;i++) |
||
316 | ax88796Write(RDMAPORT, localBuffer[i]); |
||
317 | } |
||
318 | |||
319 | |||
320 | void ax88796EndPacketSend(void) |
||
321 | { |
||
322 | //send the contents of the transmit buffer onto the network |
||
323 | ax88796Write(CR,(RD2|TXP)); |
||
324 | |||
325 | // clear the remote DMA interrupt |
||
326 | ax88796Write(ISR, RDC); |
||
327 | } |
||
328 | |||
329 | |||
330 | unsigned int ax88796BeginPacketRetreive(void) |
||
331 | { |
||
332 | unsigned char writePagePtr; |
||
333 | unsigned char readPagePtr; |
||
334 | unsigned char bnryPagePtr; |
||
335 | unsigned char i; |
||
336 | |||
337 | unsigned char pageheader[4]; |
||
338 | unsigned int rxlen; |
||
339 | |||
340 | // check for and handle an overflow |
||
341 | ax88796ProcessInterrupt(); |
||
342 | |||
343 | // read CURR from page 1 |
||
344 | ax88796Write(CR,(PS0|RD2|START)); |
||
345 | writePagePtr = ax88796Read(CURR); |
||
346 | // read the boundary register from page 0 |
||
347 | ax88796Write(CR,(RD2|START)); |
||
348 | bnryPagePtr = ax88796Read(BNRY); |
||
349 | |||
350 | // first packet is at page bnryPtr+1 |
||
351 | readPagePtr = bnryPagePtr+1; |
||
352 | if(readPagePtr >= RXSTOP_INIT) readPagePtr = RXSTART_INIT; |
||
353 | |||
354 | // return if there is no packet in the buffer |
||
355 | if( readPagePtr == writePagePtr ) |
||
356 | { |
||
357 | return 0; |
||
358 | } |
||
359 | |||
360 | // clear the packet received interrupt flag |
||
361 | ax88796Write(ISR, PRX); |
||
362 | |||
363 | // if the boundary pointer is invalid, |
||
364 | // reset the contents of the buffer and exit |
||
365 | if( (bnryPagePtr < RXSTART_INIT) || (bnryPagePtr >= RXSTOP_INIT) ) |
||
366 | { |
||
367 | ax88796Write(BNRY, RXSTART_INIT); |
||
368 | ax88796Write(CR, (PS0|RD2|START)); |
||
369 | ax88796Write(CURR, RXSTART_INIT+1); |
||
370 | ax88796Write(CR, (RD2|START)); |
||
371 | |||
372 | // rprintf("B"); |
||
373 | return 0; |
||
374 | } |
||
375 | |||
376 | // initiate DMA to transfer the RTL8019 packet header |
||
377 | ax88796Write(RBCR0, 4); |
||
378 | ax88796Write(RBCR1, 0); |
||
379 | ax88796Write(RSAR0, 0); |
||
380 | ax88796Write(RSAR1, readPagePtr); |
||
381 | ax88796Write(CR, (RD0|START)); |
||
382 | for(i=0;i<4;i++) |
||
383 | pageheader[i] = ax88796Read(RDMAPORT); |
||
384 | |||
385 | // end the DMA operation |
||
386 | ax88796Write(CR, (RD2|START)); |
||
387 | for(i = 0; i <= 20; i++) |
||
388 | if(ax88796Read(ISR) & RDC) |
||
389 | break; |
||
390 | ax88796Write(ISR, RDC); |
||
391 | |||
392 | rxlen = (pageheader[PKTHEADER_PKTLENH]<<8) + pageheader[PKTHEADER_PKTLENL]; |
||
393 | NextPage = pageheader[PKTHEADER_NEXTPAGE]; |
||
394 | |||
395 | CurrentRetreiveAddress = (readPagePtr<<8) + 4; |
||
396 | |||
397 | // if the NextPage pointer is invalid, the packet is not ready yet - exit |
||
398 | if( (NextPage >= RXSTOP_INIT) || (NextPage < RXSTART_INIT) ) |
||
399 | { |
||
400 | // rprintf("N"); |
||
401 | // rprintfu08(nextPage); |
||
402 | return 0; |
||
403 | } |
||
404 | |||
405 | return rxlen-4; |
||
406 | } |
||
407 | |||
408 | |||
409 | void ax88796RetreivePacketData(unsigned char * localBuffer, unsigned int length) |
||
410 | { |
||
411 | unsigned int i; |
||
412 | |||
413 | // initiate DMA to transfer the data |
||
414 | ax88796Write(RBCR0, (unsigned char)length); |
||
415 | ax88796Write(RBCR1, (unsigned char)(length>>8)); |
||
416 | ax88796Write(RSAR0, (unsigned char)CurrentRetreiveAddress); |
||
417 | ax88796Write(RSAR1, (unsigned char)(CurrentRetreiveAddress>>8)); |
||
418 | ax88796Write(CR, (RD0|START)); |
||
419 | for(i=0;i<length;i++) |
||
420 | localBuffer[i] = ax88796Read(RDMAPORT); |
||
421 | |||
422 | // end the DMA operation |
||
423 | ax88796Write(CR, (RD2|START)); |
||
424 | for(i = 0; i <= 20; i++) |
||
425 | if(ax88796Read(ISR) & RDC) |
||
426 | break; |
||
427 | ax88796Write(ISR, RDC); |
||
428 | |||
429 | CurrentRetreiveAddress += length; |
||
430 | if( CurrentRetreiveAddress >= 0x6000 ) |
||
431 | CurrentRetreiveAddress -= (0x6000-0x4600) ; |
||
432 | } |
||
433 | |||
434 | |||
435 | void ax88796EndPacketRetreive(void) |
||
436 | { |
||
437 | unsigned char i; |
||
438 | unsigned char bnryPagePtr; |
||
439 | |||
440 | // end the DMA operation |
||
441 | ax88796Write(CR, (RD2|START)); |
||
442 | for(i = 0; i <= 20; i++) |
||
443 | if(ax88796Read(ISR) & RDC) |
||
444 | break; |
||
445 | ax88796Write(ISR, RDC); |
||
446 | |||
447 | // set the boundary register to point |
||
448 | // to the start of the next packet-1 |
||
449 | bnryPagePtr = NextPage-1; |
||
450 | if(bnryPagePtr < RXSTART_INIT) bnryPagePtr = RXSTOP_INIT-1; |
||
451 | |||
452 | ax88796Write(BNRY, bnryPagePtr); |
||
453 | } |
||
454 | |||
455 | |||
456 | void ax88796ProcessInterrupt(void) |
||
457 | { |
||
458 | unsigned char intr = ax88796Read(ISR); |
||
459 | |||
460 | // check for receive overflow |
||
461 | if( intr & OVW ) |
||
462 | ax88796ReceiveOverflowRecover(); |
||
463 | } |
||
464 | |||
465 | |||
466 | void ax88796ReceiveOverflowRecover(void) |
||
467 | { |
||
468 | // receive buffer overflow handling procedure |
||
469 | // as specified in the AX88796 datasheet |
||
470 | |||
471 | unsigned char cmdReg; |
||
472 | unsigned char resend=0; |
||
473 | |||
474 | // check if we were transmitting something |
||
475 | cmdReg = ax88796Read(CR); |
||
476 | // stop the interface |
||
477 | ax88796Write(CR, (RD2|STOP)); |
||
478 | // wait for timeout |
||
479 | delay_ms(2); |
||
480 | // clear remote byte count registers |
||
481 | ax88796Write(RBCR0, 0x00); |
||
482 | ax88796Write(RBCR1, 0x00); |
||
483 | |||
484 | // if we were transmitting something |
||
485 | if(cmdReg & TXP) |
||
486 | { |
||
487 | // check if the transmit completed |
||
488 | cmdReg = ax88796Read(ISR); |
||
489 | if((cmdReg & PTX) || (cmdReg & TXE)) |
||
490 | resend = 0; // transmit completed |
||
491 | else |
||
492 | resend = 1; // transmit was interrupted, must resend |
||
493 | } |
||
494 | // switch to loopback mode |
||
495 | ax88796Write(TCR, LB0); |
||
496 | // start the interface |
||
497 | ax88796Write(CR, (RD2|START)); |
||
498 | // set boundary |
||
499 | ax88796Write(BNRY, RXSTART_INIT); |
||
500 | // go to page 1 |
||
501 | ax88796Write(CR, (PS0|RD2|START)); |
||
502 | // set current page register |
||
503 | ax88796Write(CPR, RXSTART_INIT+1); |
||
504 | // go to page 0 |
||
505 | ax88796Write(CR, (RD2|START)); |
||
506 | // clear the overflow int |
||
507 | ax88796Write(ISR, OVW); |
||
508 | // switch to normal (non-loopback mode) |
||
509 | ax88796Write(TCR, TCR_INIT); |
||
510 | |||
511 | // if previous transmit was interrupted, then resend |
||
512 | if(resend) |
||
513 | ax88796Write(CR, (RD2|TXP|START)); |
||
514 | |||
515 | // recovery completed |
||
516 | } |
||
517 | |||
518 | |||
519 | #define set_mdc ax88796Write(MEMR,ax88796Read(MEMR)|0x01); |
||
520 | #define clr_mdc ax88796Write(MEMR,ax88796Read(MEMR)&0xFE); |
||
521 | |||
522 | #define mii_clk set_mdc; clr_mdc; |
||
523 | |||
524 | #define set_mdir ax88796Write(MEMR,ax88796Read(MEMR)|0x02); |
||
525 | #define clr_mdir ax88796Write(MEMR,ax88796Read(MEMR)&0xFD); |
||
526 | |||
527 | #define set_mdo ax88796Write(MEMR,ax88796Read(MEMR)|0x08) |
||
528 | #define clr_mdo ax88796Write(MEMR,ax88796Read(MEMR)&0xF7) |
||
529 | |||
530 | #define mii_write clr_mdo; mii_clk; \ |
||
531 | set_mdo; mii_clk; \ |
||
532 | clr_mdo; mii_clk; \ |
||
533 | set_mdo; mii_clk; |
||
534 | |||
535 | #define mii_read clr_mdo; mii_clk; \ |
||
536 | set_mdo; mii_clk; \ |
||
537 | set_mdo; mii_clk; \ |
||
538 | clr_mdo; mii_clk; |
||
539 | |||
540 | #define mii_r_ta mii_clk; \ |
||
541 | |||
542 | #define mii_w_ta set_mdo; mii_clk; \ |
||
543 | clr_mdo; mii_clk; |
||
544 | |||
545 | void ax88796WriteMii(unsigned char phyad,unsigned char regad,unsigned int mii_data) |
||
546 | { |
||
547 | unsigned char mask8; |
||
548 | unsigned int i,mask16; |
||
549 | |||
550 | mii_write; |
||
551 | |||
552 | mask8 = 0x10; |
||
553 | for(i=0;i<5;++i) |
||
554 | { |
||
555 | if(mask8 & phyad) |
||
556 | set_mdo; |
||
557 | else |
||
558 | clr_mdo; |
||
559 | mii_clk; |
||
560 | mask8 >>= 1; |
||
561 | } |
||
562 | mask8 = 0x10; |
||
563 | for(i=0;i<5;++i) |
||
564 | { |
||
565 | if(mask8 & regad) |
||
566 | set_mdo; |
||
567 | else |
||
568 | clr_mdo; |
||
569 | mii_clk; |
||
570 | mask8 >>= 1; |
||
571 | } |
||
572 | mii_w_ta; |
||
573 | |||
574 | mask16 = 0x8000; |
||
575 | for(i=0;i<16;++i) |
||
576 | { |
||
577 | if(mask16 & mii_data) |
||
578 | set_mdo; |
||
579 | else |
||
580 | clr_mdo; |
||
581 | mii_clk; |
||
582 | mask16 >>= 1; |
||
583 | } |
||
584 | } |
||
585 | |||
586 | unsigned int ax88796ReadMii(unsigned char phyad,unsigned char regad) |
||
587 | { |
||
588 | unsigned char mask8,i; |
||
589 | unsigned int mask16,result16; |
||
590 | |||
591 | mii_read; |
||
592 | |||
593 | mask8 = 0x10; |
||
594 | for(i=0;i<5;++i) |
||
595 | { |
||
596 | if(mask8 & phyad) |
||
597 | set_mdo; |
||
598 | else |
||
599 | clr_mdo; |
||
600 | mii_clk; |
||
601 | mask8 >>= 1; |
||
602 | } |
||
603 | mask8 = 0x10; |
||
604 | for(i=0;i<5;++i) |
||
605 | { |
||
606 | if(mask8 & regad) |
||
607 | set_mdo; |
||
608 | else |
||
609 | clr_mdo; |
||
610 | mii_clk; |
||
611 | mask8 >>= 1; |
||
612 | } |
||
613 | |||
614 | mii_r_ta; |
||
615 | |||
616 | mask16 = 0x8000; |
||
617 | result16 = 0x0000; |
||
618 | for(i=0;i<16;++i) |
||
619 | { |
||
620 | mii_clk; |
||
621 | if(ax88796Read(MEMR) & 0x04) |
||
622 | { |
||
623 | result16 |= mask16; |
||
624 | } |
||
625 | else |
||
626 | { |
||
627 | asm volatile ("nop"); |
||
628 | break; |
||
629 | } |
||
630 | mask16 >>= 1; |
||
631 | } |
||
632 | return result16; |
||
633 | } |
||
634 | |||
635 | |||
636 | void ax88796RegDump(void) |
||
637 | { |
||
638 | unsigned char result; |
||
639 | result = ax88796Read(TR); |
||
640 | |||
641 | rprintf("Media State: "); |
||
642 | if(!(result & AUTOD)) |
||
643 | rprintf("Autonegotiation\r\n"); |
||
644 | else if(result & RST_B) |
||
645 | rprintf("PHY in Reset \r\n"); |
||
646 | else if(!(result & RST_10B)) |
||
647 | rprintf("10BASE-T \r\n"); |
||
648 | else if(!(result & RST_TXB)) |
||
649 | rprintf("100BASE-T \r\n"); |
||
650 | |||
651 | //rprintf("TR regsiter : %x\r\n",result); |
||
652 | //result = read_mii(0x10,0); |
||
653 | //rprintf("MII regsiter 0x10: %x\r\n",result); |
||
654 | |||
655 | rprintfProgStrM("Page0: CR BNRY PSR PST ISR TSR RSR MMR TR GPI\r\n"); |
||
656 | rprintfProgStrM(" "); |
||
657 | rprintfu08(ax88796Read(CR)); |
||
658 | rprintfProgStrM(" "); |
||
659 | rprintfu08(ax88796Read(BNRY)); |
||
660 | rprintfProgStrM(" "); |
||
661 | rprintfu08(ax88796Read(PSTART)); |
||
662 | rprintfProgStrM(" "); |
||
663 | rprintfu08(ax88796Read(PSTOP)); |
||
664 | rprintfProgStrM(" "); |
||
665 | rprintfu08(ax88796Read(ISR)); |
||
666 | rprintfProgStrM(" "); |
||
667 | rprintfu08(ax88796Read(TSR)); |
||
668 | rprintfProgStrM(" "); |
||
669 | rprintfu08(ax88796Read(RSR)); |
||
670 | rprintfProgStrM(" "); |
||
671 | rprintfu08(ax88796Read(MEMR)); |
||
672 | rprintfProgStrM(" "); |
||
673 | rprintfu08(ax88796Read(TR)); |
||
674 | rprintfProgStrM(" "); |
||
675 | rprintfu08(ax88796Read(GPI)); |
||
676 | rprintfCRLF(); |
||
677 | |||
678 | ax88796Write(CR,ax88796Read(CR)|PS0); |
||
679 | |||
680 | rprintf("Page1: CR PAR CPR\r\n"); |
||
681 | rprintfProgStrM(" "); |
||
682 | rprintfu08(ax88796Read(CR)); |
||
683 | rprintfProgStrM(" "); |
||
684 | rprintfChar(ax88796Read(PAR0)); |
||
685 | rprintfChar(ax88796Read(PAR1)); |
||
686 | rprintfChar(ax88796Read(PAR2)); |
||
687 | rprintfChar(ax88796Read(PAR3)); |
||
688 | rprintfChar(ax88796Read(PAR4)); |
||
689 | rprintfChar(ax88796Read(PAR5)); |
||
690 | rprintfProgStrM(" "); |
||
691 | rprintfu08(ax88796Read(CPR)); |
||
692 | |||
693 | ax88796Write(CR,ax88796Read(CR)&~PS0); |
||
694 | |||
695 | delay_ms(25); |
||
696 | } |
||
697 | |||
698 | /* |
||
699 | unsigned char ax88796ReceiveEmpty(void) |
||
700 | { |
||
701 | unsigned char temp; |
||
702 | |||
703 | // read CPR from page 1 |
||
704 | ax88796Write(CR,0x62); |
||
705 | temp = ax88796Read(CPR); |
||
706 | |||
707 | // return to page 0 |
||
708 | ax88796Write(CR,0x22); |
||
709 | |||
710 | return ( ax88796Read(BNRY) == temp ); |
||
711 | |||
712 | }*/ |
||
713 | |||
714 | |||
715 | |||
716 |
Powered by WebSVN v2.8.3