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

library

?curdirlinks? -

Blame information for rev 6

Line No. Rev Author Line
1 6 kaklik /*! \file cs8900.c \brief Crystal CS8900 Ethernet Interface Driver. */
2 //*****************************************************************************
3 //
4 // File Name : 'cs8900.c'
5 // Title : Crystal CS8900 Ethernet Interface Driver
6 // Author : Pascal Stang
7 // Created : 11/7/2004
8 // Revised : 11/7/2004
9 // Version : 0.1
10 // Target MCU : Atmel AVR series
11 // Editor Tabs : 4
12 //
13 //*****************************************************************************
14  
15 #include "global.h"
16 #include "timer.h"
17 #include "rprintf.h"
18  
19 #include "cs8900.h"
20  
21 // include configuration
22 #include "cs8900conf.h"
23  
24 void nicInit(void)
25 {
26 cs8900Init();
27 }
28  
29 void nicSend(unsigned int len, unsigned char* packet)
30 {
31 u08 timeout = 15;
32  
33 // request space in CS8900's on-chip memory for storing an outgoing frame
34 cs8900Write16(CS8900_IO_TXCMD, TX_START_ALL_BYTES);
35 cs8900Write16(CS8900_IO_TXLENGTH, len);
36 // check if CS8900 is ready to accept the frame we want to send
37 // (timeout after 1.5ms since it should only take 1.25ms to
38 // finish sending previous frame. If we timeout, it's probably
39 // because there's no link, no ethernet cable.)
40 while(!(cs8900ReadReg(PP_BusST) & READY_FOR_TX_NOW) && timeout)
41 {
42 // wait 100us
43 delay_us(100);
44 timeout--;
45 }
46 // write packet data bytes
47 cs8900CopyToFrame(packet, len);
48  
49 // packet is automatically sent upon completion of above write
50 }
51  
52 unsigned int nicPoll(unsigned int maxlen, unsigned char* packet)
53 {
54 unsigned int packetLength;
55  
56 packetLength = cs8900BeginPacketRetreive();
57  
58 // if there's no packet or an error - exit without ending the operation
59 if( !packetLength )
60 return 0;
61  
62 // drop anything too big for the buffer
63 if( packetLength > maxlen )
64 {
65 cs8900EndPacketRetreive();
66 return 0;
67 }
68  
69 // copy the packet data into the packet buffer
70 cs8900RetreivePacketData( packet, packetLength );
71 cs8900EndPacketRetreive();
72  
73 return packetLength;
74 }
75  
76 void nicGetMacAddress(u08* macaddr)
77 {
78 // read MAC address registers
79 // TODO: check byte order here!
80 *((unsigned short*)(macaddr+0)) = cs8900ReadReg(PP_IA+0);
81 *((unsigned short*)(macaddr+2)) = cs8900ReadReg(PP_IA+2);
82 *((unsigned short*)(macaddr+4)) = cs8900ReadReg(PP_IA+4);
83 }
84  
85 void nicSetMacAddress(u08* macaddr)
86 {
87 // write MAC address registers
88 cs8900WriteReg(PP_IA+0, (macaddr[1]<<8) + macaddr[0] );
89 cs8900WriteReg(PP_IA+2, (macaddr[3]<<8) + macaddr[2] );
90 cs8900WriteReg(PP_IA+4, (macaddr[5]<<8) + macaddr[4] );
91 }
92  
93 unsigned int cs8900BeginPacketRetreive(void)
94 {
95 unsigned short status;
96  
97 // check RxEvent
98 status = cs8900ReadReg(PP_RxEvent);
99  
100 if( !((status&RX_OK)||(status&RX_IA)||(status&RX_BROADCAST)) )
101 {
102 return 0;
103 }
104  
105 // return cs8900ReadReg(PP_RxFrameByteCnt);
106 // read RxStatus high-byte first
107 status = cs8900Read(CS8900_IO_RXTX_DATA_PORT0+1)<<8;
108 status |= cs8900Read(CS8900_IO_RXTX_DATA_PORT0+0);
109 // read packet length high-byte first
110 status = cs8900Read(CS8900_IO_RXTX_DATA_PORT0+1)<<8;
111 status |= cs8900Read(CS8900_IO_RXTX_DATA_PORT0+0);
112  
113 return status;
114 }
115  
116 void cs8900RetreivePacketData(u08* packet, unsigned int packetLength )
117 {
118 cs8900CopyFromFrame(packet, packetLength);
119 }
120  
121 void cs8900EndPacketRetreive(void)
122 {
123 // dummy read first four bytes
124 //cs8900CopyFromFrame(packet, 4);
125 }
126  
127  
128  
129 void cs8900InitPorts(void)
130 {
131 #if MEMORY_MAPPED_NIC == 1
132 // enable external SRAM interface - no wait states
133 sbi(MCUSR, SRE);
134 #else
135 // set address port to output
136 outb(CS8900_ADDRESS_DDR, CS8900_ADDRESS_MASK);
137  
138 // set data port to input with pull-ups
139 outb(CS8900_DATA_DDR, 0x00);
140 outb(CS8900_DATA_PORT, 0xFF);
141  
142 // initialize the control port read and write pins to de-asserted
143 sbi( CS8900_CONTROL_PORT, CS8900_CONTROL_READPIN );
144 sbi( CS8900_CONTROL_PORT, CS8900_CONTROL_WRITEPIN );
145 // set the read and write pins to output
146 sbi( CS8900_CONTROL_DDR, CS8900_CONTROL_READPIN );
147 sbi( CS8900_CONTROL_DDR, CS8900_CONTROL_WRITEPIN );
148 #endif
149 // set reset pin to output
150 sbi( CS8900_RESET_DDR, CS8900_RESET_PIN );
151 }
152  
153 void cs8900Init(void)
154 {
155 cs8900InitPorts();
156  
157 // assert hardware reset
158 sbi( CS8900_RESET_PORT, CS8900_RESET_PIN );
159 // wait
160 delay_ms(10);
161 // release hardware reset
162 cbi( CS8900_RESET_PORT, CS8900_RESET_PIN );
163 delay_ms(10);
164  
165 // Reset the Ethernet-Controller
166 cs8900Write16(CS8900_IO_PP_PTR, PP_SelfCTL);
167 cs8900Write16(CS8900_IO_PP_DATA_PORT0, POWER_ON_RESET);
168 // wait until chip-reset is done
169 cs8900Write16(CS8900_IO_PP_PTR, PP_SelfST);
170 while(!(cs8900Read16(CS8900_IO_PP_DATA_PORT0) & INIT_DONE));
171  
172 // set our MAC as Individual Address
173 cs8900WriteReg(PP_IA+0, (CS8900_MAC1<<8) + CS8900_MAC0 );
174 cs8900WriteReg(PP_IA+2, (CS8900_MAC3<<8) + CS8900_MAC2 );
175 cs8900WriteReg(PP_IA+4, (CS8900_MAC5<<8) + CS8900_MAC4 );
176 // configure the Physical Interface
177 cs8900WriteReg(PP_LineCTL, SERIAL_RX_ON | SERIAL_TX_ON);
178 cs8900WriteReg(PP_RxCTL, RX_OK_ACCEPT | RX_IA_ACCEPT | RX_BROADCAST_ACCEPT );
179 }
180  
181 void cs8900Write(unsigned char address, unsigned char data)
182 {
183 // assert the address
184 outb(CS8900_ADDRESS_PORT, address | (inb(CS8900_ADDRESS_PORT)&~CS8900_ADDRESS_MASK));
185 // set data bus as output
186 outb(CS8900_DATA_DDR, 0xFF);
187 // place data on bus
188 outb(CS8900_DATA_PORT, data);
189 // clock write pin
190 cbi(CS8900_CONTROL_PORT, CS8900_CONTROL_WRITEPIN);
191 nop();
192 nop();
193 nop();
194 nop();
195 sbi(CS8900_CONTROL_PORT, CS8900_CONTROL_WRITEPIN);
196 // set data bus back to input with pullups enabled
197 outb(CS8900_DATA_DDR, 0x00);
198 outb(CS8900_DATA_PORT, 0xFF);
199 }
200  
201 unsigned char cs8900Read(unsigned char address)
202 {
203 unsigned char data;
204 // assert the address
205 outb(CS8900_ADDRESS_PORT, address | (inb(CS8900_ADDRESS_PORT)&~CS8900_ADDRESS_MASK));
206 // set data bus to input with pullups enabled
207 outb(CS8900_DATA_DDR, 0x00);
208 outb(CS8900_DATA_PORT, 0xFF);
209 // assert read
210 cbi(CS8900_CONTROL_PORT, CS8900_CONTROL_READPIN);
211 nop();
212 nop();
213 nop();
214 nop();
215 // read in the data
216 data = inb( CS8900_DATA_PIN );
217 // negate read
218 sbi(CS8900_CONTROL_PORT, CS8900_CONTROL_READPIN);
219 // return data
220 return data;
221 }
222  
223 void cs8900Write16(unsigned char address, unsigned short data)
224 {
225 cs8900Write(address+0, data);
226 cs8900Write(address+1, data>>8);
227 }
228  
229 unsigned short cs8900Read16(unsigned char address)
230 {
231 unsigned short data;
232 data = cs8900Read(address+0);
233 data |= cs8900Read(address+1)<<8;
234 return data;
235 }
236  
237 // writes a word in little-endian byte order to a specified PacketPage address
238 void cs8900WriteReg(unsigned short address, unsigned short data)
239 {
240 cs8900Write16(CS8900_IO_PP_PTR, address);
241 cs8900Write16(CS8900_IO_PP_DATA_PORT0, data);
242 }
243  
244 // reads a word in little-endian byte order from a specified PacketPage address
245 unsigned short cs8900ReadReg(unsigned short address)
246 {
247 cs8900Write16(CS8900_IO_PP_PTR, address);
248 return cs8900Read16(CS8900_IO_PP_DATA_PORT0);
249 }
250  
251 // copies bytes from MCU-memory to frame port
252 // NOTES: * an odd number of byte may only be transfered
253 // if the frame is written to the end!
254 // * MCU-memory MUST start at word-boundary
255  
256 void cs8900CopyToFrame(unsigned char *source, unsigned short size)
257 {
258 while(size>1)
259 {
260 cs8900Write16(CS8900_IO_RXTX_DATA_PORT0, *((unsigned short*)source));
261 source += 2;
262 size -= 2;
263 }
264 // if odd num. of bytes...
265 // write leftover byte (the LAN-controller ignores the highbyte)
266 if(size)
267 cs8900Write16(CS8900_IO_RXTX_DATA_PORT0, *(unsigned char*)source);
268 }
269  
270 // copies bytes from frame port to MCU-memory
271 // NOTES: * an odd number of byte may only be transfered
272 // if the frame is read to the end!
273 // * MCU-memory MUST start at word-boundary
274  
275 void cs8900CopyFromFrame(unsigned char *dest, unsigned short size)
276 {
277 while(size>1)
278 {
279 *((unsigned short *)dest) = cs8900Read16(CS8900_IO_RXTX_DATA_PORT0);
280 dest += 2;
281 size -= 2;
282 }
283  
284 // check for leftover byte...
285 // the LAN-Controller will return 0 for the highbyte
286 if(size)
287 *(unsigned char *)dest = cs8900Read16(CS8900_IO_RXTX_DATA_PORT0);
288 }
289  
290 void cs8900IORegDump(void)
291 {
292 rprintfProgStrM("CS8900 I/O Registers\r\n");
293 rprintfProgStrM(" FRAME ISQ ADDR DATA0 DATA1\r\n");
294 rprintfProgStrM("-------------------------------\r\n");
295 rprintfProgStrM(" ");
296 rprintfu16(cs8900Read16(CS8900_IO_RXTX_DATA_PORT0));
297 rprintfProgStrM(" ");
298 rprintfu16(cs8900Read16(CS8900_IO_ISQ));
299 rprintfProgStrM(" ");
300 rprintfu16(cs8900Read16(CS8900_IO_PP_PTR));
301 rprintfProgStrM(" ");
302 rprintfu16(cs8900Read16(CS8900_IO_PP_DATA_PORT0));
303 rprintfProgStrM(" ");
304 rprintfu16(cs8900Read16(CS8900_IO_PP_DATA_PORT1));
305 rprintfCRLF();
306 }
307  
308 void cs8900RegDump(void)
309 {
310 rprintfProgStrM("CS8900 PacketPage Registers\r\n");
311 rprintfProgStrM("CHIP ID: ");
312 rprintfu16(cs8900ReadReg(PP_ChipID));
313 rprintfCRLF();
314  
315 rprintfProgStrM("PP_ISAIOB: ");
316 rprintfu16(cs8900ReadReg(PP_ISAIOB));
317 rprintfCRLF();
318  
319 rprintfProgStrM("MAC addr: ");
320 rprintfu16(cs8900ReadReg(PP_IA+0));
321 rprintfu16(cs8900ReadReg(PP_IA+2));
322 rprintfu16(cs8900ReadReg(PP_IA+4));
323 rprintfCRLF();
324 }
325  
326 void nicRegDump(void)
327 {
328 cs8900IORegDump();
329 cs8900RegDump();
330 }
331  
332  
333 u08 cs8900LinkStatus(void)
334 {
335 if(cs8900ReadReg(PP_LineST) & LINK_OK)
336 return 1;
337 else
338 return 0;
339 }
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3