<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Procyon AVRlib: net/cs8900.c Source File</title>
<link href="dox.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.2 -->
<div class="qindex"><a class="qindex" href="main.html">Main Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data Structures</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File List</a> | <a class="qindex" href="functions.html">Data Fields</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related Pages</a></div>
<div class="nav">
<a class="el" href="dir_000001.html">net</a></div>
<h1>cs8900.c</h1><a href="cs8900_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre class="fragment">00001 <span class="comment">/*! \file cs8900.c \brief Crystal CS8900 Ethernet Interface Driver. */</span>
00002 <span class="comment">//*****************************************************************************</span>
00003 <span class="comment">//</span>
00004 <span class="comment">// File Name : 'cs8900.c'</span>
00005 <span class="comment">// Title : Crystal CS8900 Ethernet Interface Driver</span>
00006 <span class="comment">// Author : Pascal Stang</span>
00007 <span class="comment">// Created : 11/7/2004</span>
00008 <span class="comment">// Revised : 11/7/2004</span>
00009 <span class="comment">// Version : 0.1</span>
00010 <span class="comment">// Target MCU : Atmel AVR series</span>
00011 <span class="comment">// Editor Tabs : 4</span>
00012 <span class="comment">//</span>
00013 <span class="comment">//*****************************************************************************</span>
00014
00015 <span class="preprocessor">#include "<a class="code" href="global_8h.html">global.h</a>"</span>
00016 <span class="preprocessor">#include "<a class="code" href="timer_8h.html">timer.h</a>"</span>
00017 <span class="preprocessor">#include "<a class="code" href="rprintf_8h.html">rprintf.h</a>"</span>
00018
00019 <span class="preprocessor">#include "<a class="code" href="cs8900_8h.html">cs8900.h</a>"</span>
00020
00021 <span class="comment">// include configuration</span>
00022 <span class="preprocessor">#include "<a class="code" href="cs8900conf_8h.html">cs8900conf.h</a>"</span>
00023
<a name="l00024"></a><a class="code" href="group__nic.html#ga0">00024</a> <span class="keywordtype">void</span> <a class="code" href="group__nic.html#ga0">nicInit</a>(<span class="keywordtype">void</span>)
00025 {
00026 cs8900Init();
00027 }
00028
<a name="l00029"></a><a class="code" href="group__nic.html#ga1">00029</a> <span class="keywordtype">void</span> <a class="code" href="group__nic.html#ga1">nicSend</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> len, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>* packet)
00030 {
00031 u08 timeout = 15;
00032
00033 <span class="comment">// request space in CS8900's on-chip memory for storing an outgoing frame</span>
00034 cs8900Write16(CS8900_IO_TXCMD, TX_START_ALL_BYTES);
00035 cs8900Write16(CS8900_IO_TXLENGTH, len);
00036 <span class="comment">// check if CS8900 is ready to accept the frame we want to send</span>
00037 <span class="comment">// (timeout after 1.5ms since it should only take 1.25ms to</span>
00038 <span class="comment">// finish sending previous frame. If we timeout, it's probably</span>
00039 <span class="comment">// because there's no link, no ethernet cable.)</span>
00040 <span class="keywordflow">while</span>(!(cs8900ReadReg(PP_BusST) & READY_FOR_TX_NOW) && timeout)
00041 {
00042 <span class="comment">// wait 100us</span>
00043 delay_us(100);
00044 timeout--;
00045 }
00046 <span class="comment">// write packet data bytes</span>
00047 cs8900CopyToFrame(packet, len);
00048
00049 <span class="comment">// packet is automatically sent upon completion of above write</span>
00050 }
00051
<a name="l00052"></a><a class="code" href="group__nic.html#ga2">00052</a> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> <a class="code" href="group__nic.html#ga2">nicPoll</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> maxlen, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>* packet)
00053 {
00054 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> packetLength;
00055
00056 packetLength = cs8900BeginPacketRetreive();
00057
00058 <span class="comment">// if there's no packet or an error - exit without ending the operation</span>
00059 <span class="keywordflow">if</span>( !packetLength )
00060 <span class="keywordflow">return</span> 0;
00061
00062 <span class="comment">// drop anything too big for the buffer</span>
00063 <span class="keywordflow">if</span>( packetLength > maxlen )
00064 {
00065 cs8900EndPacketRetreive();
00066 <span class="keywordflow">return</span> 0;
00067 }
00068
00069 <span class="comment">// copy the packet data into the packet buffer</span>
00070 cs8900RetreivePacketData( packet, packetLength );
00071 cs8900EndPacketRetreive();
00072
00073 <span class="keywordflow">return</span> packetLength;
00074 }
00075
00076 <span class="keywordtype">void</span> nicGetMacAddress(u08* macaddr)
00077 {
00078 <span class="comment">// read MAC address registers</span>
00079 <span class="comment">// TODO: check byte order here!</span>
00080 *((<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span>*)(macaddr+0)) = cs8900ReadReg(PP_IA+0);
00081 *((<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span>*)(macaddr+2)) = cs8900ReadReg(PP_IA+2);
00082 *((<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span>*)(macaddr+4)) = cs8900ReadReg(PP_IA+4);
00083 }
00084
00085 <span class="keywordtype">void</span> nicSetMacAddress(u08* macaddr)
00086 {
00087 <span class="comment">// write MAC address registers</span>
00088 cs8900WriteReg(PP_IA+0, (macaddr[1]<<8) + macaddr[0] );
00089 cs8900WriteReg(PP_IA+2, (macaddr[3]<<8) + macaddr[2] );
00090 cs8900WriteReg(PP_IA+4, (macaddr[5]<<8) + macaddr[4] );
00091 }
00092
00093 <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> cs8900BeginPacketRetreive(<span class="keywordtype">void</span>)
00094 {
00095 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> status;
00096
00097 <span class="comment">// check RxEvent</span>
00098 status = cs8900ReadReg(PP_RxEvent);
00099
00100 <span class="keywordflow">if</span>( !((status&RX_OK)||(status&RX_IA)||(status&RX_BROADCAST)) )
00101 {
00102 <span class="keywordflow">return</span> 0;
00103 }
00104
00105 <span class="comment">// return cs8900ReadReg(PP_RxFrameByteCnt);</span>
00106 <span class="comment">// read RxStatus high-byte first</span>
00107 status = cs8900Read(CS8900_IO_RXTX_DATA_PORT0+1)<<8;
00108 status |= cs8900Read(CS8900_IO_RXTX_DATA_PORT0+0);
00109 <span class="comment">// read packet length high-byte first</span>
00110 status = cs8900Read(CS8900_IO_RXTX_DATA_PORT0+1)<<8;
00111 status |= cs8900Read(CS8900_IO_RXTX_DATA_PORT0+0);
00112
00113 <span class="keywordflow">return</span> status;
00114 }
00115
00116 <span class="keywordtype">void</span> cs8900RetreivePacketData(u08* packet, <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> packetLength )
00117 {
00118 cs8900CopyFromFrame(packet, packetLength);
00119 }
00120
00121 <span class="keywordtype">void</span> cs8900EndPacketRetreive(<span class="keywordtype">void</span>)
00122 {
00123 <span class="comment">// dummy read first four bytes</span>
00124 <span class="comment">//cs8900CopyFromFrame(packet, 4);</span>
00125 }
00126
00127
00128
00129 <span class="keywordtype">void</span> cs8900InitPorts(<span class="keywordtype">void</span>)
00130 {
00131 <span class="preprocessor">#if MEMORY_MAPPED_NIC == 1</span>
00132 <span class="preprocessor"></span> <span class="comment">// enable external SRAM interface - no wait states</span>
00133 sbi(MCUSR, SRE);
00134 <span class="preprocessor">#else</span>
00135 <span class="preprocessor"></span> <span class="comment">// set address port to output</span>
00136 outb(CS8900_ADDRESS_DDR, CS8900_ADDRESS_MASK);
00137
00138 <span class="comment">// set data port to input with pull-ups</span>
00139 outb(CS8900_DATA_DDR, 0x00);
00140 outb(CS8900_DATA_PORT, 0xFF);
00141
00142 <span class="comment">// initialize the control port read and write pins to de-asserted</span>
00143 sbi( CS8900_CONTROL_PORT, CS8900_CONTROL_READPIN );
00144 sbi( CS8900_CONTROL_PORT, CS8900_CONTROL_WRITEPIN );
00145 <span class="comment">// set the read and write pins to output</span>
00146 sbi( CS8900_CONTROL_DDR, CS8900_CONTROL_READPIN );
00147 sbi( CS8900_CONTROL_DDR, CS8900_CONTROL_WRITEPIN );
00148 <span class="preprocessor">#endif</span>
00149 <span class="preprocessor"></span> <span class="comment">// set reset pin to output</span>
00150 sbi( CS8900_RESET_DDR, CS8900_RESET_PIN );
00151 }
00152
00153 <span class="keywordtype">void</span> cs8900Init(<span class="keywordtype">void</span>)
00154 {
00155 cs8900InitPorts();
00156
00157 <span class="comment">// assert hardware reset</span>
00158 sbi( CS8900_RESET_PORT, CS8900_RESET_PIN );
00159 <span class="comment">// wait</span>
00160 delay_ms(10);
00161 <span class="comment">// release hardware reset</span>
00162 cbi( CS8900_RESET_PORT, CS8900_RESET_PIN );
00163 delay_ms(10);
00164
00165 <span class="comment">// Reset the Ethernet-Controller</span>
00166 cs8900Write16(CS8900_IO_PP_PTR, PP_SelfCTL);
00167 cs8900Write16(CS8900_IO_PP_DATA_PORT0, POWER_ON_RESET);
00168 <span class="comment">// wait until chip-reset is done</span>
00169 cs8900Write16(CS8900_IO_PP_PTR, PP_SelfST);
00170 <span class="keywordflow">while</span>(!(cs8900Read16(CS8900_IO_PP_DATA_PORT0) & INIT_DONE));
00171
00172 <span class="comment">// set our MAC as Individual Address</span>
00173 cs8900WriteReg(PP_IA+0, (CS8900_MAC1<<8) + CS8900_MAC0 );
00174 cs8900WriteReg(PP_IA+2, (CS8900_MAC3<<8) + CS8900_MAC2 );
00175 cs8900WriteReg(PP_IA+4, (CS8900_MAC5<<8) + CS8900_MAC4 );
00176 <span class="comment">// configure the Physical Interface</span>
00177 cs8900WriteReg(PP_LineCTL, SERIAL_RX_ON | SERIAL_TX_ON);
00178 cs8900WriteReg(PP_RxCTL, RX_OK_ACCEPT | RX_IA_ACCEPT | RX_BROADCAST_ACCEPT );
00179 }
00180
00181 <span class="keywordtype">void</span> cs8900Write(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> address, <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> data)
00182 {
00183 <span class="comment">// assert the address</span>
00184 outb(CS8900_ADDRESS_PORT, address | (inb(CS8900_ADDRESS_PORT)&~CS8900_ADDRESS_MASK));
00185 <span class="comment">// set data bus as output</span>
00186 outb(CS8900_DATA_DDR, 0xFF);
00187 <span class="comment">// place data on bus</span>
00188 outb(CS8900_DATA_PORT, data);
00189 <span class="comment">// clock write pin</span>
00190 cbi(CS8900_CONTROL_PORT, CS8900_CONTROL_WRITEPIN);
00191 nop();
00192 nop();
00193 nop();
00194 nop();
00195 sbi(CS8900_CONTROL_PORT, CS8900_CONTROL_WRITEPIN);
00196 <span class="comment">// set data bus back to input with pullups enabled</span>
00197 outb(CS8900_DATA_DDR, 0x00);
00198 outb(CS8900_DATA_PORT, 0xFF);
00199 }
00200
00201 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> cs8900Read(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> address)
00202 {
00203 <span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> data;
00204 <span class="comment">// assert the address</span>
00205 outb(CS8900_ADDRESS_PORT, address | (inb(CS8900_ADDRESS_PORT)&~CS8900_ADDRESS_MASK));
00206 <span class="comment">// set data bus to input with pullups enabled</span>
00207 outb(CS8900_DATA_DDR, 0x00);
00208 outb(CS8900_DATA_PORT, 0xFF);
00209 <span class="comment">// assert read</span>
00210 cbi(CS8900_CONTROL_PORT, CS8900_CONTROL_READPIN);
00211 nop();
00212 nop();
00213 nop();
00214 nop();
00215 <span class="comment">// read in the data</span>
00216 data = inb( CS8900_DATA_PIN );
00217 <span class="comment">// negate read</span>
00218 sbi(CS8900_CONTROL_PORT, CS8900_CONTROL_READPIN);
00219 <span class="comment">// return data</span>
00220 <span class="keywordflow">return</span> data;
00221 }
00222
00223 <span class="keywordtype">void</span> cs8900Write16(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> address, <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> data)
00224 {
00225 cs8900Write(address+0, data);
00226 cs8900Write(address+1, data>>8);
00227 }
00228
00229 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> cs8900Read16(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> address)
00230 {
00231 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> data;
00232 data = cs8900Read(address+0);
00233 data |= cs8900Read(address+1)<<8;
00234 <span class="keywordflow">return</span> data;
00235 }
00236
00237 <span class="comment">// writes a word in little-endian byte order to a specified PacketPage address</span>
00238 <span class="keywordtype">void</span> cs8900WriteReg(<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> address, <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> data)
00239 {
00240 cs8900Write16(CS8900_IO_PP_PTR, address);
00241 cs8900Write16(CS8900_IO_PP_DATA_PORT0, data);
00242 }
00243
00244 <span class="comment">// reads a word in little-endian byte order from a specified PacketPage address</span>
00245 <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> cs8900ReadReg(<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> address)
00246 {
00247 cs8900Write16(CS8900_IO_PP_PTR, address);
00248 <span class="keywordflow">return</span> cs8900Read16(CS8900_IO_PP_DATA_PORT0);
00249 }
00250
00251 <span class="comment">// copies bytes from MCU-memory to frame port</span>
00252 <span class="comment">// NOTES: * an odd number of byte may only be transfered</span>
00253 <span class="comment">// if the frame is written to the end!</span>
00254 <span class="comment">// * MCU-memory MUST start at word-boundary</span>
00255
00256 <span class="keywordtype">void</span> cs8900CopyToFrame(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *source, <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> size)
00257 {
00258 <span class="keywordflow">while</span>(size>1)
00259 {
00260 cs8900Write16(CS8900_IO_RXTX_DATA_PORT0, *((<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span>*)source));
00261 source += 2;
00262 size -= 2;
00263 }
00264 <span class="comment">// if odd num. of bytes...</span>
00265 <span class="comment">// write leftover byte (the LAN-controller ignores the highbyte)</span>
00266 <span class="keywordflow">if</span>(size)
00267 cs8900Write16(CS8900_IO_RXTX_DATA_PORT0, *(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span>*)source);
00268 }
00269
00270 <span class="comment">// copies bytes from frame port to MCU-memory</span>
00271 <span class="comment">// NOTES: * an odd number of byte may only be transfered</span>
00272 <span class="comment">// if the frame is read to the end!</span>
00273 <span class="comment">// * MCU-memory MUST start at word-boundary</span>
00274
00275 <span class="keywordtype">void</span> cs8900CopyFromFrame(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *dest, <span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> size)
00276 {
00277 <span class="keywordflow">while</span>(size>1)
00278 {
00279 *((<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> *)dest) = cs8900Read16(CS8900_IO_RXTX_DATA_PORT0);
00280 dest += 2;
00281 size -= 2;
00282 }
00283
00284 <span class="comment">// check for leftover byte...</span>
00285 <span class="comment">// the LAN-Controller will return 0 for the highbyte</span>
00286 <span class="keywordflow">if</span>(size)
00287 *(<span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *)dest = cs8900Read16(CS8900_IO_RXTX_DATA_PORT0);
00288 }
00289
00290 <span class="keywordtype">void</span> cs8900IORegDump(<span class="keywordtype">void</span>)
00291 {
00292 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"CS8900 I/O Registers\r\n"</span>);
00293 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">" FRAME ISQ ADDR DATA0 DATA1\r\n"</span>);
00294 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"-------------------------------\r\n"</span>);
00295 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">" "</span>);
00296 <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(cs8900Read16(CS8900_IO_RXTX_DATA_PORT0));
00297 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">" "</span>);
00298 <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(cs8900Read16(CS8900_IO_ISQ));
00299 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">" "</span>);
00300 <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(cs8900Read16(CS8900_IO_PP_PTR));
00301 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">" "</span>);
00302 <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(cs8900Read16(CS8900_IO_PP_DATA_PORT0));
00303 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">" "</span>);
00304 <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(cs8900Read16(CS8900_IO_PP_DATA_PORT1));
00305 <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
00306 }
00307
00308 <span class="keywordtype">void</span> cs8900RegDump(<span class="keywordtype">void</span>)
00309 {
00310 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"CS8900 PacketPage Registers\r\n"</span>);
00311 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"CHIP ID: "</span>);
00312 <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(cs8900ReadReg(PP_ChipID));
00313 <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
00314
00315 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"PP_ISAIOB: "</span>);
00316 <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(cs8900ReadReg(PP_ISAIOB));
00317 <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
00318
00319 <a class="code" href="group__rprintf.html#ga15">rprintfProgStrM</a>(<span class="stringliteral">"MAC addr: "</span>);
00320 <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(cs8900ReadReg(PP_IA+0));
00321 <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(cs8900ReadReg(PP_IA+2));
00322 <a class="code" href="group__rprintf.html#ga8">rprintfu16</a>(cs8900ReadReg(PP_IA+4));
00323 <a class="code" href="group__rprintf.html#ga5">rprintfCRLF</a>();
00324 }
00325
<a name="l00326"></a><a class="code" href="group__nic.html#ga5">00326</a> <span class="keywordtype">void</span> <a class="code" href="group__nic.html#ga5">nicRegDump</a>(<span class="keywordtype">void</span>)
00327 {
00328 cs8900IORegDump();
00329 cs8900RegDump();
00330 }
00331
00332
00333 u08 cs8900LinkStatus(<span class="keywordtype">void</span>)
00334 {
00335 <span class="keywordflow">if</span>(cs8900ReadReg(PP_LineST) & LINK_OK)
00336 <span class="keywordflow">return</span> 1;
00337 <span class="keywordflow">else</span>
00338 <span class="keywordflow">return</span> 0;
00339 }
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Sun Oct 29 03:41:07 2006 for Procyon AVRlib by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.2 </small></address>
</body>
</html>
|