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

library

?curdirlinks? - Rev 6

?prevdifflink? - Blame - ?getfile?

<!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&nbsp;Page</a> | <a class="qindex" href="modules.html">Modules</a> | <a class="qindex" href="annotated.html">Data&nbsp;Structures</a> | <a class="qindex" href="dirs.html">Directories</a> | <a class="qindex" href="files.html">File&nbsp;List</a> | <a class="qindex" href="functions.html">Data&nbsp;Fields</a> | <a class="qindex" href="globals.html">Globals</a> | <a class="qindex" href="pages.html">Related&nbsp;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) &amp; READY_FOR_TX_NOW) &amp;&amp; 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 &gt; 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]&lt;&lt;8) + macaddr[0] );
00089     cs8900WriteReg(PP_IA+2, (macaddr[3]&lt;&lt;8) + macaddr[2] );
00090     cs8900WriteReg(PP_IA+4, (macaddr[5]&lt;&lt;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&amp;RX_OK)||(status&amp;RX_IA)||(status&amp;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)&lt;&lt;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)&lt;&lt;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) &amp; INIT_DONE));
00171 
00172     <span class="comment">// set our MAC as Individual Address</span>
00173     cs8900WriteReg(PP_IA+0, (CS8900_MAC1&lt;&lt;8) + CS8900_MAC0 );
00174     cs8900WriteReg(PP_IA+2, (CS8900_MAC3&lt;&lt;8) + CS8900_MAC2 );
00175     cs8900WriteReg(PP_IA+4, (CS8900_MAC5&lt;&lt;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)&amp;~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)&amp;~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&gt;&gt;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)&lt;&lt;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&gt;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&gt;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) &amp; 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&nbsp;
<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>
{FILE END}
{FOOTER START}

Powered by WebSVN v2.8.3