cs8900.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2002-2003 by Call Direct Cellular Solutions Pty. Ltd. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. All advertising materials mentioning features or use of this
00014  *    software must display the following acknowledgement:
00015  *
00016  *    This product includes software developed by Call Direct Cellular Solutions Pty. Ltd.
00017  *    and its contributors.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY CALL DIRECT CELLULAR SOLUTIONS AND CONTRIBUTORS
00020  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00021  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00022  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CALL DIRECT
00023  * CELLULAR SOLUTIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00024  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00025  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00026  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00027  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00028  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00029  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00030  * SUCH DAMAGE.
00031  *
00032  * For additional information see http://www.calldirect.com.au/
00033  *
00034  * -
00035  * Copyright (C) 2001-2003 by egnite Software GmbH. All rights reserved.
00036  *
00037  * Redistribution and use in source and binary forms, with or without
00038  * modification, are permitted provided that the following conditions
00039  * are met:
00040  *
00041  * 1. Redistributions of source code must retain the above copyright
00042  *    notice, this list of conditions and the following disclaimer.
00043  * 2. Redistributions in binary form must reproduce the above copyright
00044  *    notice, this list of conditions and the following disclaimer in the
00045  *    documentation and/or other materials provided with the distribution.
00046  * 3. All advertising materials mentioning features or use of this
00047  *    software must display the following acknowledgement:
00048  *
00049  *    This product includes software developed by egnite Software GmbH
00050  *    and its contributors.
00051  *
00052  * THIS SOFTWARE IS PROVIDED BY EGNITE SOFTWARE GMBH AND CONTRIBUTORS
00053  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00054  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00055  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL EGNITE
00056  * SOFTWARE GMBH OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00057  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00058  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
00059  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
00060  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00061  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
00062  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00063  * SUCH DAMAGE.
00064  *
00065  * For additional information see http://www.ethernut.de/
00066  *
00067  * -
00068  * Portions Copyright (C) 2000 David J. Hudson <dave@humbug.demon.co.uk>
00069  *
00070  * This file is distributed in the hope that it will be useful, but WITHOUT
00071  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00072  * FITNESS FOR A PARTICULAR PURPOSE.
00073  *
00074  * You can redistribute this file and/or modify it under the terms of the GNU
00075  * General Public License (GPL) as published by the Free Software Foundation;
00076  * either version 2 of the License, or (at your discretion) any later version.
00077  * See the accompanying file "copying-gpl.txt" for more details.
00078  *
00079  * As a special exception to the GPL, permission is granted for additional
00080  * uses of the text contained in this file.  See the accompanying file
00081  * "copying-liquorice.txt" for details.
00082  * -
00083  * Portions Copyright (c) 1983, 1993 by
00084  *  The Regents of the University of California.  All rights reserved.
00085  *
00086  * Redistribution and use in source and binary forms, with or without
00087  * modification, are permitted provided that the following conditions
00088  * are met:
00089  * 1. Redistributions of source code must retain the above copyright
00090  *    notice, this list of conditions and the following disclaimer.
00091  * 2. Redistributions in binary form must reproduce the above copyright
00092  *    notice, this list of conditions and the following disclaimer in the
00093  *    documentation and/or other materials provided with the distribution.
00094  * 3. All advertising materials mentioning features or use of this software
00095  *    must display the following acknowledgement:
00096  *  This product includes software developed by the University of
00097  *  California, Berkeley and its contributors.
00098  * 4. Neither the name of the University nor the names of its contributors
00099  *    may be used to endorse or promote products derived from this software
00100  *    without specific prior written permission.
00101  *
00102  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
00103  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00104  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00105  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
00106  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00107  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00108  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00109  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00110  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00111  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00112  * SUCH DAMAGE.
00113  * -
00114  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
00115  *
00116  * Permission to use, copy, modify, and distribute this software for any
00117  * purpose with or without fee is hereby granted, provided that the above
00118  * copyright notice and this permission notice appear in all copies, and that
00119  * the name of Digital Equipment Corporation not be used in advertising or
00120  * publicity pertaining to distribution of the document or software without
00121  * specific, written prior permission.
00122  * 
00123  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
00124  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
00125  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
00126  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
00127  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
00128  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
00129  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
00130  * SOFTWARE.
00131  */
00132 
00133 /*
00134  * $Log: cs8900.c,v $
00135  * Revision 1.2  2006/10/08 16:48:07  haraldkipp
00136  * Documentation fixed
00137  *
00138  * Revision 1.1  2005/07/26 18:02:27  haraldkipp
00139  * Moved from dev.
00140  *
00141  * Revision 1.9  2005/04/30 16:42:41  chaac
00142  * Fixed bug in handling of NUTDEBUG. Added include for cfg/os.h. If NUTDEBUG
00143  * is defined in NutConf, it will make effect where it is used.
00144  *
00145  * Revision 1.8  2004/05/26 09:40:30  olereinhardt
00146  * Changed reading of packet length / receive status to be compatible with
00147  * newer AVRGCC versions. (Need to read high byte first!)
00148  *
00149  * Added software reset / wakeup routine to init code. (only avalilable in new code)
00150  *
00151  * Revision 1.7  2004/05/25 11:39:47  olereinhardt
00152  * Define NUT_CS8900_OLD to get the old functionality back again
00153  *
00154  * Revision 1.6  2004/05/24 17:09:17  olereinhardt
00155  * Changed base address handling in cs8900.c and moved cs8900.h to /include/dev
00156  * Base address can now be passed to the nic driver by NutRegisterDevice.
00157  * Removed some Assembler code in cs8900.c
00158  *
00159  * Added some databus waitstate settings for the upper half of the address space in os/arch/avr_nutinit.c. Now three waitstates are default for 0x8000-0xFFFF
00160  *
00161  * Added terminal device driver for hd44780 compatible LCD displays directly
00162  * connected to the memory bus (memory mapped). See hd44780.c for more information.
00163  * Therefore some minor changed in include/dev/term.h and dev/term.c are needet to
00164  * pass a base address to the lcd driver.
00165  *
00166  * Revision 1.5  2004/03/18 14:06:52  haraldkipp
00167  * Deprecated header file replaced
00168  *
00169  * Revision 1.4  2003/10/13 10:13:49  haraldkipp
00170  * First release
00171  *
00172  * Revision 1.3  2003/08/05 20:11:30  haraldkipp
00173  * Removed from ICCAVR compilation
00174  *
00175  * Revision 1.2  2003/07/20 20:07:38  haraldkipp
00176  * Conflicting Ethernet driver routine names solved.
00177  *
00178  * Revision 1.1  2003/07/20 16:37:21  haraldkipp
00179  * CrystalTek 8900A driver added.
00180  *
00181  *
00182  * Revision 1.0  2002/03/28 MJC CDCS
00183  * Created
00184  *
00185  * Revision 1.1  2003/03/25 MJC CDCS
00186  * Modified behaviour when transmit buffer space unavailable
00187  *
00188  */
00189 
00190 /* Not ported. */
00191 #ifdef __GNUC__
00192 
00193 #include <cfg/os.h>
00194 #include <string.h>
00195 #include <avr/interrupt.h>
00196 
00197 #include <sys/heap.h>
00198 #include <sys/thread.h>
00199 #include <sys/event.h>
00200 #include <sys/timer.h>
00201 #include <sys/confnet.h>
00202 
00203 #include <dev/nicrtl.h>
00204 #include <netinet/if_ether.h>
00205 #include <net/ether.h>
00206 #include <net/if_var.h>
00207 #include <netinet/ip.h>
00208 
00209 #include <dev/irqreg.h>
00210 #include "cs8900.h"
00211 
00212 #ifdef NUTDEBUG
00213 #include <sys/osdebug.h>
00214 #include <net/netdebug.h>
00215 #endif
00216 
00221 
00222 
00223 // Ethernet flags byte
00224 // Bit 0 = transmit byte flag
00225 u_char cs_flags;
00226 volatile u_short cs_base = 0x0000;
00227 
00228 
00229 void CSWrite16(u_short addr, u_short data)
00230 {
00231     u_short *p;
00232 
00233     p = (u_short *) addr;
00234     cli();
00235     *p = data;
00236     sei();
00237 }
00238 
00239 void CSWritePP16(u_short addr, u_short data)
00240 {
00241     u_short *p;
00242 
00243     cli();
00244     p = (u_short *) CS_PP_PTR;
00245     *p = addr;
00246 
00247     CSWrite16(CS_PP_DATA0, data);
00248 
00249     return;
00250 }
00251 
00252 u_short CSRead16(u_short addr)
00253 {
00254     u_short *p;
00255     u_short d;
00256 
00257     cli();
00258     p = (u_short *) addr;
00259     d = *p;
00260     sei();
00261 
00262     return d;
00263 }
00264 
00265 u_short CSReadPP16(u_short addr)
00266 {
00267     u_short *p;
00268 
00269     cli();
00270     p = (u_short *) CS_PP_PTR;
00271     *p = addr;
00272 
00273     return CSRead16(CS_PP_DATA0);
00274 }
00275 
00276 u_long CSReadPP32(u_int addr)
00277 {
00278     u_long l;
00279     u_long *p;
00280 
00281     cli();
00282     p = (u_long *) CS_PP_PTR;
00283     *p = addr;
00284     p = (u_long *) CS_PP_DATA0;
00285     l = *p;
00286     sei();
00287 
00288     return l;
00289 }
00290 
00291 
00292 
00293 void CSBeginFrame(void)
00294 {
00295     cs_flags &= ~1;
00296 }
00297 
00298 void CSEndFrame(void)
00299 {
00300     u_char *p;
00301 
00302     cli();
00303     p = (u_char *) CS_DATA_P0 + 1;
00304     sei();
00305 
00306     // If odd number of bytes in packet pad it out
00307     if (cs_flags & 1)
00308         p = 0;
00309 }
00310 
00311 void CSWriteFrameByte(u_char data)
00312 {
00313     u_char *p;
00314 
00315     if (cs_flags & 1)
00316         p = (u_char *) CS_DATA_P0 + 1;
00317     else
00318         p = (u_char *) CS_DATA_P0;
00319 
00320     *p = data;
00321     cs_flags ^= 1;
00322 }
00323 
00324 static int CSEthPutPacket(NUTDEVICE * dev, NETBUF * nb)
00325 {
00326     u_short i;
00327     u_short sz;
00328     u_char *p;
00329     NICINFO *ni;
00330 
00331     ni = (NICINFO *) dev->dev_dcb;
00332 
00333     //
00334     // Calculate the number of bytes to be send. Do not
00335     // send packets larger than 1536 bytes.
00336     //
00337     sz = nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz;
00338     if (sz >= 0x600) {
00339         NutNetBufFree(nb);
00340         return -1;
00341     }
00342 #if 0
00343     if (tcp_trace) {
00344         NutPrintFormat_P(dev_debug, PSTR("[ETHTX-%u]\r\n"), sz);
00345         NutPrintFlush(dev_debug);
00346     }
00347 #endif
00348 
00349     // Start transmission after entire frame is loaded into CS8900
00350     CSWrite16(CS_TX_CMD_I, 0xC0);
00351     // Set frame size
00352     CSWrite16(CS_TX_LEN_I, sz);
00353 
00354     // Wait for buffer space, but only for a while (200ms)
00355     // If the cable is disconnected this will never become true
00356     // If we don't get the go ahead within 200ms return 0 (Sucess)
00357     // And let the upper layers deal with re-transmission 
00358     // If we return failure TCP sockets will close straight away which probably
00359     // isn't the correct behaviour
00360     i = 0;
00361     while ((CSReadPP16(CS_BUS_STAT) & 0x0100) == 0) {
00362         i++;
00363         if (i > 20)
00364             return 0;
00365         NutSleep(10);
00366     }
00367 
00368     //
00369     // Transfer ethernet physical header.
00370     //
00371     CSBeginFrame();
00372 
00373     p = nb->nb_dl.vp;
00374     for (i = 0; i < nb->nb_dl.sz; i++) {
00375         CSWriteFrameByte(*p++);
00376     }
00377 
00378 
00379     p = nb->nb_nw.vp;
00380     for (i = 0; i < nb->nb_nw.sz; i++) {
00381         CSWriteFrameByte(*p++);
00382     }
00383 
00384     p = nb->nb_tp.vp;
00385     for (i = 0; i < nb->nb_tp.sz; i++) {
00386         CSWriteFrameByte(*p++);
00387     }
00388 
00389     p = nb->nb_ap.vp;
00390     for (i = 0; i < nb->nb_ap.sz; i++) {
00391         CSWriteFrameByte(*p++);
00392     }
00393 
00394     CSEndFrame();
00395 
00396     return 0;
00397 }
00398 
00413 int CSNicOutput(NUTDEVICE * dev, NETBUF * nb)
00414 {
00415     int rc = -1;
00416     NICINFO *ni;
00417 
00418     ni = (NICINFO *) dev->dev_dcb;
00419 
00420 #if 0
00421     if (tcp_trace) {
00422         NutPrintFormat_P(dev_debug, PSTR("Enter EthOutput\r\n"));
00423         NutPrintFlush(dev_debug);
00424     }
00425 #endif
00426 
00427     if ((rc = CSEthPutPacket(dev, nb)) == 0)
00428         ni->ni_tx_packets++;
00429 
00430     return rc;
00431 }
00432 
00433 
00434 
00435 
00436 
00444 THREAD(CSNICrx, arg)
00445 {
00446     NUTDEVICE *dev;
00447     IFNET *ifn;
00448     NICINFO *ni;
00449     NETBUF *nb;
00450     u_char *p;
00451     u_char *q;
00452     u_short i, m;
00453     volatile u_short l;
00454 
00455     dev = arg;
00456     ifn = (IFNET *) dev->dev_icb;
00457     ni = (NICINFO *) dev->dev_dcb;
00458 
00459 #if 0
00460     if (tcp_trace) {
00461         NutPrintFormat_P(dev_debug, PSTR("Enter ETHReceive\r\n"));
00462         NutPrintFlush(dev_debug);
00463     }
00464 #endif
00465 
00466     l = 0;
00467 
00468     NutThreadSetPriority(8);
00469     for (;;) {
00470         while ((CSReadPP16(CS_RX_EVENT) & 0x0100) == 0) {
00471             NutSleep(10);
00472         }
00473 
00474 #ifdef NUT_CS8900_OLD
00475         // Get the RxStatus But don't let the compiler do any optomisation
00476         asm volatile ("lds __tmp_reg__, %3" "\n\t"
00477                       "mov %B0, __tmp_reg__" "\n\t" "lds __tmp_reg__, %2" "\n\t" "mov %A0, __tmp_reg__" "\n\t":"=r" (l)
00478                       :"0"(l), "n"((unsigned short) (CS_DATA_P0)), "n"((unsigned short) (CS_DATA_P0 + 1))
00479             );
00480 
00481         // Get the Packet Length But don't let the compiler do any optomisation
00482         asm volatile ("lds __tmp_reg__, %3" "\n\t"
00483                       "mov %B0, __tmp_reg__" "\n\t" "lds __tmp_reg__, %2" "\n\t" "mov %A0, __tmp_reg__" "\n\t":"=r" (l)
00484                       :"0"(l), "n"((unsigned short) (CS_DATA_P0)), "n"((unsigned short) (CS_DATA_P0 + 1))
00485             );
00486 #else
00487 
00488         l = *(u_char *) (CS_DATA_P0 + 1) << 8 | *(u_char *) (CS_DATA_P0);
00489         l = *(u_char *) (CS_DATA_P0 + 1) << 8 | *(u_char *) (CS_DATA_P0);
00490 #endif
00491         //NutPrintFormat_P(dev_debug,PSTR("RxLength = %x \r\n"), l);
00492         //NutPrintFlush(dev_debug);
00493 
00494         // Account for odd length packets
00495         if (l & 1)
00496             m = l - 1;
00497         else
00498             m = l;
00499 
00500 
00501         nb = NutNetBufAlloc(0, NBAF_DATALINK, l);
00502         if (nb) {
00503             q = nb->nb_dl.vp;
00504             for (i = 0; i < m; i += 2) {
00505                 p = (u_char *) CS_DATA_P0;
00506                 *q++ = *p;
00507                 p = (u_char *) CS_DATA_P0 + 1;
00508                 *q++ = *p;
00509             }
00510 
00511             // Odd length packets
00512             if (m != l) {
00513                 p = (u_char *) CS_DATA_P0;
00514                 *q++ = *p;
00515 
00516                 p = (u_char *) CS_DATA_P0 + 1;
00517                 m = *p;
00518             }
00519             ni->ni_rx_packets++;
00520             (*ifn->if_recv) (dev, nb);
00521         }
00522     }
00523 }
00524 
00525 void CSSoftwareWakeup(void)
00526 {
00527     volatile u_short *p;
00528 
00529     p = (u_short *) CS_PP_PTR;
00530     *p = CS_SELF_CTRL;
00531 
00532     NutDelay(10);
00533 }
00534 
00535 
00536 void CSSoftwareReset(void)
00537 {
00538     volatile u_short *p;
00539 
00540     p = (u_short *) CS_PP_PTR;
00541     *p = CS_SELF_CTRL;
00542     p = (u_short *) CS_DATA_P0;
00543     *p = 0x0040;
00544 }
00545 
00546 
00557 int CSNicInit(NUTDEVICE * dev)
00558 {
00559     u_short i;
00560     u_short j;
00561     IFNET *ifn;
00562     NICINFO *ni;
00563 
00564 #if 0
00565     if (tcp_trace) {
00566         NutPrintFormat_P(dev_debug, PSTR("Enter NicInit  \r\n"));
00567         NutPrintFlush(dev_debug);
00568     }
00569 #endif
00570     cs_base = dev->dev_base;
00571 
00572     if (confnet.cd_size == 0)
00573         NutNetLoadConfig(dev->dev_name);
00574 
00575     ifn = dev->dev_icb;
00576     memcpy(ifn->if_mac, confnet.cdn_mac, 6);
00577     memset(dev->dev_dcb, 0, sizeof(NICINFO));
00578     ni = (NICINFO *) dev->dev_dcb;
00579 
00580     // Take CS8900 out of reset and wait for internal reset to complete
00581 #ifdef NUT_CS8900_OLD
00582     outp(inp(PORTD) & ~RESETE, PORTD);
00583 #else
00584     CSSoftwareWakeup();
00585     CSSoftwareReset();
00586 #endif
00587 
00588     NutDelay(100);
00589 
00590     // Check for presence
00591     if (CSReadPP16(CS_PROD_ID) != 0x630E)
00592         return -1;
00593 
00594     //
00595     //  Copy our MAC address to the NIC
00596     // 
00597     for (i = 0; i < 6; i += 2) {
00598         j = ifn->if_mac[i] << 8;
00599         j |= ifn->if_mac[i + 1];
00600         CSWritePP16(CS_IEEE_ADDR + i, j);
00601         j = CSReadPP16(CS_IEEE_ADDR + i);
00602 #if 0
00603         if (tcp_trace) {
00604             NutPrintFormat_P(dev_debug, PSTR("ADDR = %x\r\n"), j);
00605             NutPrintFlush(dev_debug);
00606         }
00607 #endif
00608     }
00609 
00610     //
00611     // Enable the Transmitter and Receiver
00612     //
00613     CSWritePP16(CS_LINE_CTRL, 0x00C0);
00614     //i = CSReadPP16(CS_LINE_CTRL);
00615     //NutPrintFormat_P(dev_debug,PSTR("CS_LINE_CTRL = %x\r\n"), i);
00616 
00617     CSWritePP16(CS_RX_CTL, 0x0F40);
00618     //i = CSReadPP16(CS_RX_CTL);
00619     //NutPrintFormat_P(dev_debug,PSTR("CS_RX_CTL = %x\r\n"), i);
00620 
00621     // 
00622     // Start receiver thread
00623     //
00624     NutThreadCreate("csnicrx", CSNICrx, dev, 500);
00625 
00626     return 0;
00627 }
00628 
00630 #else
00631 void keep_icc_happy(void)
00632 {
00633 }
00634 
00635 #endif

© 2000-2007 by egnite Software GmbH - visit http://www.ethernut.de/