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$ 00135 * Revision 1.4 2009/01/17 11:26:37 haraldkipp 00136 * Getting rid of two remaining BSD types in favor of stdint. 00137 * Replaced 'u_int' by 'unsinged int' and 'uptr_t' by 'uintptr_t'. 00138 * 00139 * Revision 1.3 2008/08/11 06:59:14 haraldkipp 00140 * BSD types replaced by stdint types (feature request #1282721). 00141 * 00142 * Revision 1.2 2006/10/08 16:48:07 haraldkipp 00143 * Documentation fixed 00144 * 00145 * Revision 1.1 2005/07/26 18:02:27 haraldkipp 00146 * Moved from dev. 00147 * 00148 * Revision 1.9 2005/04/30 16:42:41 chaac 00149 * Fixed bug in handling of NUTDEBUG. Added include for cfg/os.h. If NUTDEBUG 00150 * is defined in NutConf, it will make effect where it is used. 00151 * 00152 * Revision 1.8 2004/05/26 09:40:30 olereinhardt 00153 * Changed reading of packet length / receive status to be compatible with 00154 * newer AVRGCC versions. (Need to read high byte first!) 00155 * 00156 * Added software reset / wakeup routine to init code. (only avalilable in new code) 00157 * 00158 * Revision 1.7 2004/05/25 11:39:47 olereinhardt 00159 * Define NUT_CS8900_OLD to get the old functionality back again 00160 * 00161 * Revision 1.6 2004/05/24 17:09:17 olereinhardt 00162 * Changed base address handling in cs8900.c and moved cs8900.h to /include/dev 00163 * Base address can now be passed to the nic driver by NutRegisterDevice. 00164 * Removed some Assembler code in cs8900.c 00165 * 00166 * 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 00167 * 00168 * Added terminal device driver for hd44780 compatible LCD displays directly 00169 * connected to the memory bus (memory mapped). See hd44780.c for more information. 00170 * Therefore some minor changed in include/dev/term.h and dev/term.c are needet to 00171 * pass a base address to the lcd driver. 00172 * 00173 * Revision 1.5 2004/03/18 14:06:52 haraldkipp 00174 * Deprecated header file replaced 00175 * 00176 * Revision 1.4 2003/10/13 10:13:49 haraldkipp 00177 * First release 00178 * 00179 * Revision 1.3 2003/08/05 20:11:30 haraldkipp 00180 * Removed from ICCAVR compilation 00181 * 00182 * Revision 1.2 2003/07/20 20:07:38 haraldkipp 00183 * Conflicting Ethernet driver routine names solved. 00184 * 00185 * Revision 1.1 2003/07/20 16:37:21 haraldkipp 00186 * CrystalTek 8900A driver added. 00187 * 00188 * 00189 * Revision 1.0 2002/03/28 MJC CDCS 00190 * Created 00191 * 00192 * Revision 1.1 2003/03/25 MJC CDCS 00193 * Modified behaviour when transmit buffer space unavailable 00194 * 00195 */ 00196 00197 /* Not ported. */ 00198 #ifdef __GNUC__ 00199 00200 #include <cfg/os.h> 00201 #include <string.h> 00202 #include <avr/interrupt.h> 00203 00204 #include <sys/heap.h> 00205 #include <sys/thread.h> 00206 #include <sys/event.h> 00207 #include <sys/timer.h> 00208 #include <sys/confnet.h> 00209 00210 #include <dev/nicrtl.h> 00211 #include <netinet/if_ether.h> 00212 #include <net/ether.h> 00213 #include <net/if_var.h> 00214 #include <netinet/ip.h> 00215 00216 #include <dev/irqreg.h> 00217 #include "cs8900.h" 00218 00219 #ifdef NUTDEBUG 00220 #include <sys/osdebug.h> 00221 #include <net/netdebug.h> 00222 #endif 00223 00228 00229 00230 // Ethernet flags byte 00231 // Bit 0 = transmit byte flag 00232 uint8_t cs_flags; 00233 volatile uint16_t cs_base = 0x0000; 00234 00235 00236 void CSWrite16(uint16_t addr, uint16_t data) 00237 { 00238 uint16_t *p; 00239 00240 p = (uint16_t *) addr; 00241 cli(); 00242 *p = data; 00243 sei(); 00244 } 00245 00246 void CSWritePP16(uint16_t addr, uint16_t data) 00247 { 00248 uint16_t *p; 00249 00250 cli(); 00251 p = (uint16_t *) CS_PP_PTR; 00252 *p = addr; 00253 00254 CSWrite16(CS_PP_DATA0, data); 00255 00256 return; 00257 } 00258 00259 uint16_t CSRead16(uint16_t addr) 00260 { 00261 uint16_t *p; 00262 uint16_t d; 00263 00264 cli(); 00265 p = (uint16_t *) addr; 00266 d = *p; 00267 sei(); 00268 00269 return d; 00270 } 00271 00272 uint16_t CSReadPP16(uint16_t addr) 00273 { 00274 uint16_t *p; 00275 00276 cli(); 00277 p = (uint16_t *) CS_PP_PTR; 00278 *p = addr; 00279 00280 return CSRead16(CS_PP_DATA0); 00281 } 00282 00283 uint32_t CSReadPP32(unsigned int addr) 00284 { 00285 uint32_t l; 00286 uint32_t *p; 00287 00288 cli(); 00289 p = (uint32_t *) CS_PP_PTR; 00290 *p = addr; 00291 p = (uint32_t *) CS_PP_DATA0; 00292 l = *p; 00293 sei(); 00294 00295 return l; 00296 } 00297 00298 00299 00300 void CSBeginFrame(void) 00301 { 00302 cs_flags &= ~1; 00303 } 00304 00305 void CSEndFrame(void) 00306 { 00307 uint8_t *p; 00308 00309 cli(); 00310 p = (uint8_t *) CS_DATA_P0 + 1; 00311 sei(); 00312 00313 // If odd number of bytes in packet pad it out 00314 if (cs_flags & 1) 00315 p = 0; 00316 } 00317 00318 void CSWriteFrameByte(uint8_t data) 00319 { 00320 uint8_t *p; 00321 00322 if (cs_flags & 1) 00323 p = (uint8_t *) CS_DATA_P0 + 1; 00324 else 00325 p = (uint8_t *) CS_DATA_P0; 00326 00327 *p = data; 00328 cs_flags ^= 1; 00329 } 00330 00331 static int CSEthPutPacket(NUTDEVICE * dev, NETBUF * nb) 00332 { 00333 uint16_t i; 00334 uint16_t sz; 00335 uint8_t *p; 00336 NICINFO *ni; 00337 00338 ni = (NICINFO *) dev->dev_dcb; 00339 00340 // 00341 // Calculate the number of bytes to be send. Do not 00342 // send packets larger than 1536 bytes. 00343 // 00344 sz = nb->nb_dl.sz + nb->nb_nw.sz + nb->nb_tp.sz + nb->nb_ap.sz; 00345 if (sz >= 0x600) { 00346 NutNetBufFree(nb); 00347 return -1; 00348 } 00349 #if 0 00350 if (tcp_trace) { 00351 NutPrintFormat_P(dev_debug, PSTR("[ETHTX-%u]\r\n"), sz); 00352 NutPrintFlush(dev_debug); 00353 } 00354 #endif 00355 00356 // Start transmission after entire frame is loaded into CS8900 00357 CSWrite16(CS_TX_CMD_I, 0xC0); 00358 // Set frame size 00359 CSWrite16(CS_TX_LEN_I, sz); 00360 00361 // Wait for buffer space, but only for a while (200ms) 00362 // If the cable is disconnected this will never become true 00363 // If we don't get the go ahead within 200ms return 0 (Sucess) 00364 // And let the upper layers deal with re-transmission 00365 // If we return failure TCP sockets will close straight away which probably 00366 // isn't the correct behaviour 00367 i = 0; 00368 while ((CSReadPP16(CS_BUS_STAT) & 0x0100) == 0) { 00369 i++; 00370 if (i > 20) 00371 return 0; 00372 NutSleep(10); 00373 } 00374 00375 // 00376 // Transfer ethernet physical header. 00377 // 00378 CSBeginFrame(); 00379 00380 p = nb->nb_dl.vp; 00381 for (i = 0; i < nb->nb_dl.sz; i++) { 00382 CSWriteFrameByte(*p++); 00383 } 00384 00385 00386 p = nb->nb_nw.vp; 00387 for (i = 0; i < nb->nb_nw.sz; i++) { 00388 CSWriteFrameByte(*p++); 00389 } 00390 00391 p = nb->nb_tp.vp; 00392 for (i = 0; i < nb->nb_tp.sz; i++) { 00393 CSWriteFrameByte(*p++); 00394 } 00395 00396 p = nb->nb_ap.vp; 00397 for (i = 0; i < nb->nb_ap.sz; i++) { 00398 CSWriteFrameByte(*p++); 00399 } 00400 00401 CSEndFrame(); 00402 00403 return 0; 00404 } 00405 00420 int CSNicOutput(NUTDEVICE * dev, NETBUF * nb) 00421 { 00422 int rc = -1; 00423 NICINFO *ni; 00424 00425 ni = (NICINFO *) dev->dev_dcb; 00426 00427 #if 0 00428 if (tcp_trace) { 00429 NutPrintFormat_P(dev_debug, PSTR("Enter EthOutput\r\n")); 00430 NutPrintFlush(dev_debug); 00431 } 00432 #endif 00433 00434 if ((rc = CSEthPutPacket(dev, nb)) == 0) 00435 ni->ni_tx_packets++; 00436 00437 return rc; 00438 } 00439 00440 00441 00442 00443 00451 THREAD(CSNICrx, arg) 00452 { 00453 NUTDEVICE *dev; 00454 IFNET *ifn; 00455 NICINFO *ni; 00456 NETBUF *nb; 00457 uint8_t *p; 00458 uint8_t *q; 00459 uint16_t i, m; 00460 volatile uint16_t l; 00461 00462 dev = arg; 00463 ifn = (IFNET *) dev->dev_icb; 00464 ni = (NICINFO *) dev->dev_dcb; 00465 00466 #if 0 00467 if (tcp_trace) { 00468 NutPrintFormat_P(dev_debug, PSTR("Enter ETHReceive\r\n")); 00469 NutPrintFlush(dev_debug); 00470 } 00471 #endif 00472 00473 l = 0; 00474 00475 NutThreadSetPriority(8); 00476 for (;;) { 00477 while ((CSReadPP16(CS_RX_EVENT) & 0x0100) == 0) { 00478 NutSleep(10); 00479 } 00480 00481 #ifdef NUT_CS8900_OLD 00482 // Get the RxStatus But don't let the compiler do any optomisation 00483 asm volatile ("lds __tmp_reg__, %3" "\n\t" 00484 "mov %B0, __tmp_reg__" "\n\t" "lds __tmp_reg__, %2" "\n\t" "mov %A0, __tmp_reg__" "\n\t":"=r" (l) 00485 :"0"(l), "n"((unsigned short) (CS_DATA_P0)), "n"((unsigned short) (CS_DATA_P0 + 1)) 00486 ); 00487 00488 // Get the Packet Length But don't let the compiler do any optomisation 00489 asm volatile ("lds __tmp_reg__, %3" "\n\t" 00490 "mov %B0, __tmp_reg__" "\n\t" "lds __tmp_reg__, %2" "\n\t" "mov %A0, __tmp_reg__" "\n\t":"=r" (l) 00491 :"0"(l), "n"((unsigned short) (CS_DATA_P0)), "n"((unsigned short) (CS_DATA_P0 + 1)) 00492 ); 00493 #else 00494 00495 l = *(uint8_t *) (CS_DATA_P0 + 1) << 8 | *(uint8_t *) (CS_DATA_P0); 00496 l = *(uint8_t *) (CS_DATA_P0 + 1) << 8 | *(uint8_t *) (CS_DATA_P0); 00497 #endif 00498 //NutPrintFormat_P(dev_debug,PSTR("RxLength = %x \r\n"), l); 00499 //NutPrintFlush(dev_debug); 00500 00501 // Account for odd length packets 00502 if (l & 1) 00503 m = l - 1; 00504 else 00505 m = l; 00506 00507 00508 nb = NutNetBufAlloc(0, NBAF_DATALINK, l); 00509 if (nb) { 00510 q = nb->nb_dl.vp; 00511 for (i = 0; i < m; i += 2) { 00512 p = (uint8_t *) CS_DATA_P0; 00513 *q++ = *p; 00514 p = (uint8_t *) CS_DATA_P0 + 1; 00515 *q++ = *p; 00516 } 00517 00518 // Odd length packets 00519 if (m != l) { 00520 p = (uint8_t *) CS_DATA_P0; 00521 *q++ = *p; 00522 00523 p = (uint8_t *) CS_DATA_P0 + 1; 00524 m = *p; 00525 } 00526 ni->ni_rx_packets++; 00527 (*ifn->if_recv) (dev, nb); 00528 } 00529 } 00530 } 00531 00532 void CSSoftwareWakeup(void) 00533 { 00534 volatile uint16_t *p; 00535 00536 p = (uint16_t *) CS_PP_PTR; 00537 *p = CS_SELF_CTRL; 00538 00539 NutDelay(10); 00540 } 00541 00542 00543 void CSSoftwareReset(void) 00544 { 00545 volatile uint16_t *p; 00546 00547 p = (uint16_t *) CS_PP_PTR; 00548 *p = CS_SELF_CTRL; 00549 p = (uint16_t *) CS_DATA_P0; 00550 *p = 0x0040; 00551 } 00552 00553 00564 int CSNicInit(NUTDEVICE * dev) 00565 { 00566 uint16_t i; 00567 uint16_t j; 00568 IFNET *ifn; 00569 NICINFO *ni; 00570 00571 #if 0 00572 if (tcp_trace) { 00573 NutPrintFormat_P(dev_debug, PSTR("Enter NicInit \r\n")); 00574 NutPrintFlush(dev_debug); 00575 } 00576 #endif 00577 cs_base = dev->dev_base; 00578 00579 if (confnet.cd_size == 0) 00580 NutNetLoadConfig(dev->dev_name); 00581 00582 ifn = dev->dev_icb; 00583 memcpy(ifn->if_mac, confnet.cdn_mac, 6); 00584 memset(dev->dev_dcb, 0, sizeof(NICINFO)); 00585 ni = (NICINFO *) dev->dev_dcb; 00586 00587 // Take CS8900 out of reset and wait for internal reset to complete 00588 #ifdef NUT_CS8900_OLD 00589 outb(PORTD, inb(PORTD) & ~RESETE); 00590 #else 00591 CSSoftwareWakeup(); 00592 CSSoftwareReset(); 00593 #endif 00594 00595 NutDelay(100); 00596 00597 // Check for presence 00598 if (CSReadPP16(CS_PROD_ID) != 0x630E) 00599 return -1; 00600 00601 // 00602 // Copy our MAC address to the NIC 00603 // 00604 for (i = 0; i < 6; i += 2) { 00605 j = ifn->if_mac[i] << 8; 00606 j |= ifn->if_mac[i + 1]; 00607 CSWritePP16(CS_IEEE_ADDR + i, j); 00608 j = CSReadPP16(CS_IEEE_ADDR + i); 00609 #if 0 00610 if (tcp_trace) { 00611 NutPrintFormat_P(dev_debug, PSTR("ADDR = %x\r\n"), j); 00612 NutPrintFlush(dev_debug); 00613 } 00614 #endif 00615 } 00616 00617 // 00618 // Enable the Transmitter and Receiver 00619 // 00620 CSWritePP16(CS_LINE_CTRL, 0x00C0); 00621 //i = CSReadPP16(CS_LINE_CTRL); 00622 //NutPrintFormat_P(dev_debug,PSTR("CS_LINE_CTRL = %x\r\n"), i); 00623 00624 CSWritePP16(CS_RX_CTL, 0x0F40); 00625 //i = CSReadPP16(CS_RX_CTL); 00626 //NutPrintFormat_P(dev_debug,PSTR("CS_RX_CTL = %x\r\n"), i); 00627 00628 // 00629 // Start receiver thread 00630 // 00631 NutThreadCreate("csnicrx", CSNICrx, dev, 500); 00632 00633 return 0; 00634 } 00635 00637 #else 00638 void keep_icc_happy(void) 00639 { 00640 } 00641 00642 #endif