11 changed files with 1311 additions and 0 deletions
@ -0,0 +1,13 @@
|
||||
This directory contains architecture and compiler specific stuff for porting lwIP |
||||
to the C16x and ST10 microcontrollers. The compiler specifics are for Tasking EDE |
||||
v7.5r2. |
||||
|
||||
The sequential API has not been ported; it's function are empties. If someone is |
||||
interested in adding a sequential API, please contact the author (see below). |
||||
|
||||
Besides this, a Cirrus (formerly Crystal Semiconductors) CS8900a Ethernet driver |
||||
is included, which assumes a 16-bit data bus configuration. When porting this |
||||
driver, note that the CS8900a does not support interrupts in 8-bit mode. |
||||
|
||||
Leon Woestenberg |
||||
<leon.woestenberg@axon.tv> |
||||
@ -0,0 +1,22 @@
|
||||
#ifndef __CC_H__ |
||||
#define __CC_H__ |
||||
|
||||
/* memset(), memcpy() */ |
||||
#include <string.h> |
||||
|
||||
typedef unsigned char u8_t; |
||||
typedef signed char s8_t; |
||||
typedef unsigned short u16_t; |
||||
typedef signed short s16_t; |
||||
typedef unsigned long u32_t; |
||||
typedef signed long s32_t; |
||||
|
||||
typedef u32_t mem_ptr_t; |
||||
|
||||
// LW: Supported in at least >=v7.5 r2, but lwIP worked without the "_packed" attribute already
|
||||
#define PACK_STRUCT_BEGIN _packed |
||||
#define PACK_STRUCT_STRUCT |
||||
#define PACK_STRUCT_END |
||||
#define PACK_STRUCT_FIELD(x) x |
||||
|
||||
#endif /* __CC_H__ */ |
||||
@ -0,0 +1,6 @@
|
||||
#ifndef __CPU_H__ |
||||
#define __CPU_H__ |
||||
|
||||
#define BYTE_ORDER LITTLE_ENDIAN |
||||
|
||||
#endif /* __CPU_H__ */ |
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Swedish Institute of Computer Science. |
||||
* All rights reserved.
|
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* |
||||
* This file is part of the lwIP TCP/IP stack. |
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se> |
||||
* |
||||
* $Id: lib.h,v 1.1 2003/01/18 18:21:57 jani Exp $ |
||||
*/ |
||||
#ifndef __LIB_H__ |
||||
#define __LIB_H__ |
||||
|
||||
|
||||
#endif /* __LIB_H__ */ |
||||
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Swedish Institute of Computer Science. |
||||
* All rights reserved.
|
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* |
||||
* This file is part of the lwIP TCP/IP stack. |
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se> |
||||
* |
||||
* $Id: perf.h,v 1.1 2003/01/18 18:21:57 jani Exp $ |
||||
*/ |
||||
#ifndef __PERF_H__ |
||||
#define __PERF_H__ |
||||
|
||||
#define PERF_START /* null definition */ |
||||
#define PERF_STOP(x) /* null definition */ |
||||
|
||||
#endif /* __PERF_H__ */ |
||||
@ -0,0 +1,15 @@
|
||||
#ifndef __SYS_ARCH_H__ |
||||
#define __SYS_ARCH_H__ |
||||
|
||||
#define SEMA int |
||||
#define QUEUE int |
||||
#define TASK int |
||||
|
||||
#define SYS_MBOX_NULL (QUEUE)0 |
||||
#define SYS_SEM_NULL (SEMA)0 |
||||
|
||||
typedef SEMA sys_sem_t; |
||||
typedef QUEUE sys_mbox_t; |
||||
typedef TASK sys_thread_t; |
||||
|
||||
#endif /* __SYS_ARCH_H__ */ |
||||
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2003 Leon Woestenberg <leon.woestenberg@axon.tv> |
||||
* Copyright (c) 2001-2003 Axon Digital Design B.V., The Netherlands. |
||||
* All rights reserved. |
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met: |
||||
* |
||||
* 1. Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, |
||||
* this list of conditions and the following disclaimer in the documentation |
||||
* and/or other materials provided with the distribution. |
||||
* 3. The name of the author may not be used to endorse or promote products |
||||
* derived from this software without specific prior written permission.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE. |
||||
* |
||||
* This file is part of the lwIP TCP/IP stack. |
||||
*
|
||||
* Author: Leon Woestenberg <leon.woestenberg@axon.tv> |
||||
* |
||||
* This is a device driver for the Crystal Semiconductor CS8900 |
||||
* chip in combination with the lwIP stack. |
||||
* |
||||
* This is work under development. Please coordinate changes |
||||
* and requests with Leon Woestenberg <leon.woestenberg@axon.tv> |
||||
* |
||||
* The Swedish Institute of Computer Science and Adam Dunkels |
||||
* are specifically granted permission to redistribute this |
||||
* source code under any conditions they seem fit. |
||||
* |
||||
*/ |
||||
#ifndef __NETIF_CS8900IF_H__ |
||||
#define __NETIF_CS8900IF_H__ |
||||
|
||||
#include "lwip/netif.h" |
||||
|
||||
/* interface statistics gathering
|
||||
* such as collisions, dropped packets, missed packets |
||||
* 0 = no statistics, minimal memory requirements, no overhead
|
||||
* 1 = statistics on, but some have large granularity (0x200), very low overhead |
||||
* 2 = statistics on, updated on every call to cs8900_service(), low overhead |
||||
*/ |
||||
#define CS8900_STATS 2 |
||||
|
||||
struct cs8900if |
||||
{ |
||||
//struct eth_addr *ethaddr;
|
||||
u8_t needs_service; |
||||
u8_t use_polling; |
||||
#if (CS8900_STATS > 0) |
||||
u32_t interrupts; // #interrupt requests of cs8900
|
||||
u32_t missed; // #packets on medium that could not enter cs8900a chip due to buffer shortage
|
||||
u32_t dropped; // #packets dropped after they have been received in chip buffer
|
||||
u32_t collisions; // #collisions on medium when transmitting packets
|
||||
u32_t sentpackets; // #number of sent packets
|
||||
u32_t sentbytes; // #number of sent bytes
|
||||
#endif |
||||
/* Add whatever per-interface state that is needed here. */ |
||||
}; |
||||
|
||||
void cs8900if_init(struct netif *); |
||||
void cs8900if_service(struct netif *); |
||||
void cs8900if_input(struct netif *netif); |
||||
err_t cs8900if_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr); |
||||
|
||||
void cs8900_send_debug(unsigned char *p, unsigned int len); |
||||
|
||||
#endif /* __NETIF_CS8900IF_H__ */ |
||||
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Swedish Institute of Computer Science. |
||||
* All rights reserved.
|
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* |
||||
* This file is part of the lwIP TCP/IP stack. |
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se> |
||||
* |
||||
* $Id: lib.c,v 1.1 2003/01/18 18:21:57 jani Exp $ |
||||
*/ |
||||
|
||||
/* These are generic implementations of various library functions used
|
||||
* throughout the lwIP code. When porting, those should be optimized |
||||
* for the particular processor architecture, preferably coded in |
||||
* assembler. |
||||
*/ |
||||
|
||||
#include "lwip/arch.h" |
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
u16_t |
||||
htons(u16_t n) |
||||
{ |
||||
return ((n & 0xff) << 8) | ((n & 0xff00) >> 8); |
||||
} |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
u16_t |
||||
ntohs(u16_t n) |
||||
{ |
||||
return htons(n); |
||||
} |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
u32_t |
||||
htonl(u32_t n) |
||||
{ |
||||
return ((n & 0xff) << 24) | |
||||
((n & 0xff00) << 8) | |
||||
((n & 0xff0000) >> 8) | |
||||
((n & 0xff000000) >> 24); |
||||
} |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
u32_t |
||||
ntohl(u32_t n) |
||||
{ |
||||
return htonl(n); |
||||
} |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */ |
||||
@ -0,0 +1,844 @@
|
||||
/** @file
|
||||
/*
|
||||
* Copyright (c) 2001, 2002 Leon Woestenberg <leon.woestenberg@axon.tv> |
||||
* Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands. |
||||
* All rights reserved. |
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met: |
||||
* |
||||
* 1. Redistributions of source code must retain the above copyright notice, |
||||
* this list of conditions and the following disclaimer. |
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, |
||||
* this list of conditions and the following disclaimer in the documentation |
||||
* and/or other materials provided with the distribution. |
||||
* 3. The name of the author may not be used to endorse or promote products |
||||
* derived from this software without specific prior written permission.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE. |
||||
* |
||||
* This file is part of the lwIP TCP/IP stack. |
||||
*
|
||||
* Author: Leon Woestenberg <leon.woestenberg@axon.tv> |
||||
* |
||||
* This is a device driver for the Crystal Semiconductor CS8900 |
||||
* chip in combination with the lwIP stack. |
||||
* |
||||
* This is work under development. Please coordinate changes |
||||
* and requests with Leon Woestenberg <leon.woestenberg@axon.tv> |
||||
* |
||||
* The Swedish Institute of Computer Science and Adam Dunkels |
||||
* are specifically granted permission to redistribute this |
||||
* source code under any conditions they seem fit. |
||||
* |
||||
* A quick function roadmap: |
||||
* |
||||
* cs8900_*() are low level, cs8900 hardware specific functions. |
||||
* These are declared static in the device driver source and |
||||
* SHOULD NOT need to be called from outside this source. |
||||
* |
||||
* cs8900if_*() are the lwIP network interface functions. |
||||
*
|
||||
* cs8900_interrupt() is an early interrupt service routine (ISR). |
||||
* It merely sets a flag to indicate the cs8900 needs servicing. |
||||
* (This function MAY be tied to an interrupt vector, IF present). |
||||
* |
||||
* cs8900_service() is the actual interrupt event service routine. |
||||
* It must be called whenever the cs8900 needs servicing. It MAY |
||||
* be polled safely (so, you do NOT NEED interrupt support.) |
||||
* |
||||
* cs8900_init() sets up the cs8900, using its register set. When |
||||
* using the driver on your particular hardware platform, make sure |
||||
* the register setups match. |
||||
* Function is called from cs8900if_init(). |
||||
* |
||||
* cs8900_input() transfers a received packet from the chip. |
||||
* Function is called from cs8900if_input(). |
||||
* |
||||
* cs8900_output() transfers a packet to the chip for transmission. |
||||
* Function is called from cs8900if_output(). |
||||
* |
||||
* cs8900if_init() initializes the lwIP network interface, and |
||||
* calls cs8900_init() to initialize the hardware. |
||||
* Function is called from lwIP. |
||||
*
|
||||
* cs8900if_service() is the service routine, which must be called |
||||
* upon the need for service, or on a regular basis, in order to |
||||
* service the Ethernet chip. |
||||
* |
||||
* cs8900if_input() calls cs8900_input() to get a received packet |
||||
* and then forwards the packet to protocol(s) handler(s). |
||||
* Function is called from cs8900_service(). |
||||
* |
||||
* cs8900if_output() resolves the hardware address, then |
||||
* calls cs8900_output() to transfer the packet. |
||||
* Function is called from lwIP. |
||||
* |
||||
* Future development: |
||||
*
|
||||
* Split the generic Ethernet functionality (a lot of the |
||||
* cs8900if_*() functions) and the actual cs8900a dependencies. |
||||
* |
||||
* Enhance the interrupt handler to service the Ethernet |
||||
* chip (to decrease latency); support early packet |
||||
* inspection (during reception) to early drop unwanted |
||||
* packets, minimize chip buffer use and maximize throughput. |
||||
* |
||||
* Statistics gathering, currently under development. |
||||
* SNMP support, currently under development. |
||||
* |
||||
*/ |
||||
|
||||
#include "lwip/debug.h" |
||||
|
||||
#include "lwip/opt.h" |
||||
#include "lwip/def.h" |
||||
#include "lwip/mem.h" |
||||
#include "lwip/pbuf.h" |
||||
#include "lwip/stats.h" |
||||
#include "lwip/sys.h" |
||||
#include "netif/etharp.h" |
||||
|
||||
#if 0 |
||||
// include some debugging help
|
||||
# define DBG_LEVEL 1 |
||||
# include "leds.h" |
||||
# include "display.h" |
||||
//# include "page.h"
|
||||
# define LED_NEED_SERVICE LED_FP1 |
||||
#else |
||||
// no debugging
|
||||
# define leds_on() |
||||
# define leds_off() |
||||
#endif |
||||
|
||||
#include "cs8900if.h" |
||||
#if LWIP_SNMP > 0 |
||||
# include "snmp.h" |
||||
#endif |
||||
|
||||
// Define those to better describe your network interface
|
||||
#define IFNAME0 'e' |
||||
#define IFNAME1 'n' |
||||
|
||||
static const struct eth_addr ethbroadcast = {{0xffU,0xffU,0xffU,0xffU,0xffU,0xffU}}; |
||||
|
||||
// Forward declarations
|
||||
static err_t cs8900_output(struct netif *netif, struct pbuf *p); |
||||
static struct pbuf *cs8900_input(struct netif *netif); |
||||
static void cs8900_service(struct netif *netif); |
||||
static u32_t cs8900_chksum(void *dataptr, int len); |
||||
|
||||
// Define these to match your hardware setup
|
||||
#define MEM_BASE 0x00E000 |
||||
#define IO_BASE 0x800 |
||||
#define INT_NR 0x00 |
||||
|
||||
#define RXTXREG *((volatile u16_t *)(MEM_BASE + IO_BASE)) |
||||
#define TXCMD *((volatile u16_t *)(MEM_BASE + IO_BASE + 0x04)) |
||||
#define TXLENGTH *((volatile u16_t *)(MEM_BASE + IO_BASE + 0x06)) |
||||
#define ISQ *((volatile u16_t *)(MEM_BASE + IO_BASE + 0x08)) |
||||
#define PACKETPP *((volatile u16_t *)(MEM_BASE + IO_BASE + 0x0A)) |
||||
#define PPDATA *((volatile u16_t *)(MEM_BASE + IO_BASE + 0x0C)) |
||||
|
||||
// CS8900 PacketPage register offsets
|
||||
#define CS_PP_EISA 0x0000 // EISA Registration number of CS8900
|
||||
#define CS_PP_PRODID 0x0002 // Product ID Number
|
||||
#define CS_PP_IOBASE 0x0020 // I/O Base Address
|
||||
#define CS_PP_INTNUM 0x0022 // Interrupt number (0,1,2, or 3)
|
||||
#define CS_PP_RXCFG 0x0102 // Receiver Configuration
|
||||
#define CS_PP_RXCTL 0x0104 // Receiver Control
|
||||
#define CS_PP_TXCFG 0x0106 // Transmit Configuration
|
||||
#define CS_PP_BUFCFG 0x010A // Buffer Configuration
|
||||
#define CS_PP_LINECTL 0x0112 // Line Control Register offset
|
||||
#define CS_PP_SELFCTL 0x0114 // Self Control
|
||||
#define CS_PP_BUSCTL 0x0116 // Bus Control
|
||||
#define CS_PP_TESTCTL 0x0118 // Test Control
|
||||
#define CS_PP_ISQ 0x0120 // Interrupt status queue
|
||||
#define CS_PP_RXEVENT 0x0124 // Receiver Event
|
||||
#define CS_PP_TX_EVENT 0x0128 // Transmitter Event
|
||||
#define CS_PP_BUF_EVENT 0x012C // Buffer Event
|
||||
#define CS_PP_RXMISS 0x0130 // Receiver Miss Counter
|
||||
#define CS_PP_TXCOL 0x0132 // Transmit Collision Counter
|
||||
#define CS_PP_LINESTATUS 0x0134 // Line Status
|
||||
#define CS_PP_SELFTEST 0x0136 // Self Status
|
||||
#define CS_PP_BUSSTATUS 0x0138 // Bus Status
|
||||
#define CS_PP_TXCMD 0x0144 // Transmit Command Request
|
||||
#define CS_PP_TXLEN 0x0146 // Transmit Length
|
||||
#define CS_PP_IA1 0x0158 // Individual Address (IA)
|
||||
#define CS_PP_IA2 0x015A // Individual Address (IA)
|
||||
#define CS_PP_IA3 0x015C // Individual Address (IA)
|
||||
|
||||
#define CS_PP_RXSTATUS 0x0400 // Receive Status
|
||||
#define CS_PP_RXLEN 0x0402 // Receive Length
|
||||
#define CS_PP_RXFRAME 0x0404 // Receive Frame Location
|
||||
#define CS_PP_TXFRAME 0x0A00 // Transmit Frame Location
|
||||
|
||||
|
||||
// removed interrupt from library
|
||||
#if 0 |
||||
// hardware interrupt vector handler
|
||||
_interrupt(0x18) void cs8900_interrupt(void) |
||||
{ |
||||
struct cs8900if *cs8900if = cs8900if_netif->state; |
||||
// network interface is configured?
|
||||
if (cs8900if != NULL) |
||||
{ |
||||
// chip needs service
|
||||
cs8900if->needs_service = 1; |
||||
#if (CS8900_STATS > 0) |
||||
cs8900if->interrupts++; |
||||
#endif |
||||
} |
||||
#ifdef LED_NEED_SERVICE |
||||
leds_on(LED_NEED_SERVICE); |
||||
#endif |
||||
} |
||||
#endif |
||||
|
||||
// cs8900_init()
|
||||
//
|
||||
// initializes the CS8900A chip
|
||||
//
|
||||
static void cs8900_init(struct netif *netif) |
||||
{ |
||||
#ifdef LED_NEED_SERVICE |
||||
leds_off(LED_NEED_SERVICE); |
||||
#endif |
||||
|
||||
// set RESET bit
|
||||
PACKETPP = CS_PP_SELFCTL; |
||||
PPDATA = 0x0055U; |
||||
|
||||
// { the RESET bit will be cleared by the cs8900a
|
||||
// as a result of the reset }
|
||||
// RESET bit cleared?
|
||||
while((PPDATA & 0x0040U) != 0); // TODO: add timeout
|
||||
|
||||
// { after full initialization of the cs8900a
|
||||
// the INITD bit will be set }
|
||||
|
||||
PACKETPP = CS_PP_SELFTEST; |
||||
// INITD bit still clear?
|
||||
while ((PPDATA & 0x0080U) == 0); // TODO: add timeout
|
||||
// { INITD bit is set }
|
||||
|
||||
// SIBUSY bit still set?
|
||||
while ((PPDATA & 0x0100U) == 0x0100); // TODO: add timeout
|
||||
// { SIBUSY bit clear }
|
||||
|
||||
#if 1 |
||||
{
|
||||
u16_t dummy; |
||||
// datasheet section 3.3.3
|
||||
dummy = *(u16_t *)(MEM_BASE + IO_BASE + 0x0D); |
||||
// Dummy read, put chip in 16-bit mode
|
||||
dummy = *(u16_t *)(MEM_BASE + IO_BASE + 0x0D); |
||||
} |
||||
#endif |
||||
|
||||
// Set MAC address
|
||||
PACKETPP = CS_PP_IA1; |
||||
PPDATA = (u16_t)(netif->hwaddr[0]) | (u16_t)(netif->hwaddr[1] << 8U); |
||||
PACKETPP = CS_PP_IA2; |
||||
PPDATA = (u16_t)(netif->hwaddr[2]) | (u16_t)(netif->hwaddr[3] << 8U); |
||||
PACKETPP = CS_PP_IA3; |
||||
PPDATA = (u16_t)(netif->hwaddr[4]) | (u16_t)(netif->hwaddr[5] << 8U); |
||||
|
||||
// accept valid unicast or broadcast frames
|
||||
PACKETPP = CS_PP_RXCTL; |
||||
PPDATA = (0x0005U | 0x0800U/*broadcast*/ | 0x0400U/*individual*/ | 0x0100U/*RxOK*/); |
||||
|
||||
// enable receive interrupt
|
||||
PACKETPP = CS_PP_RXCFG; |
||||
PPDATA = (0x0003U | 0x0100U/*RXIRQ*/); |
||||
|
||||
// disable transmit interrupt (is default)
|
||||
PACKETPP = CS_PP_TXCFG; |
||||
PPDATA = (0x0007U | 0); |
||||
|
||||
// use interrupt number 0
|
||||
PACKETPP = CS_PP_INTNUM; |
||||
PPDATA = (0x0000U); |
||||
|
||||
// generate interrupt event on:
|
||||
// - the RxMISS counter reaches 0x200, or
|
||||
// - a received frame is lost
|
||||
PACKETPP = CS_PP_BUFCFG; |
||||
PPDATA = (0x000bU | |
||||
#if (CS8900_STATS > 0) // interrupt before counter overflow
|
||||
(0x2000U/*MissOvfloiE*/ | 0x1000U/*TxColOvfloiE*/) | |
||||
#endif |
||||
#if (CS8900_STATS > 1) // interrupt on counter increment
|
||||
(0x0400U/*RxMissiE*/) | |
||||
#endif |
||||
0x0000); |
||||
|
||||
// enable interrupt generation
|
||||
PACKETPP = CS_PP_BUSCTL; |
||||
PPDATA = (0x0017U | 0x8000U/*EnableIRQ*/); |
||||
|
||||
// enable:
|
||||
// - receiver
|
||||
// - transmitter
|
||||
PACKETPP = CS_PP_LINECTL; |
||||
PPDATA = (0x0013U | 0x0080U/*SerTxOn*/ | 0x0040U/*SerRxOn*/); |
||||
} |
||||
|
||||
static err_t cs8900_output(struct netif *netif, struct pbuf *p) |
||||
{ |
||||
int tries = 0; |
||||
|
||||
// exit if link has failed
|
||||
PACKETPP = CS_PP_LINESTATUS; |
||||
if ((PPDATA & 0x0080U/*LinkOK*/) == 0) return ERR_CONN; // no Ethernet link
|
||||
|
||||
/* issue 'transmit' command to CS8900 */ |
||||
TXCMD = 0x00C9U; |
||||
/* send length (in bytes) of packet to send */ |
||||
TXLENGTH = p->tot_len; |
||||
|
||||
PACKETPP = CS_PP_BUSSTATUS; |
||||
// not ready for transmission and still within 100 retries?
|
||||
while(((PPDATA & 0x0100U/*Rdy4TxNOW*/) == 0) && (tries++ < 100)) |
||||
{ |
||||
// throw away the last committed received frame
|
||||
PACKETPP = CS_PP_RXCFG; |
||||
PPDATA = (0x0003U | 0x0040U/*Skip_1*/ | 0x0100U/*RxOKiE*/); |
||||
PACKETPP = CS_PP_BUSSTATUS; |
||||
/* cs8900if->dropped++; // CHECK: we do not know if we actually will drop a frame here */
|
||||
} |
||||
// ready to transmit?
|
||||
if((PPDATA & 0x0100U/*Rdy4TxNOW*/) != 0) |
||||
{ |
||||
// q traverses through linked list of pbuf's
|
||||
struct pbuf *q; |
||||
for(q = p; q != NULL; q = q->next) |
||||
{ |
||||
u16_t i; |
||||
u16_t *ptr = (u16_t *)q->payload; |
||||
// Send the data from the pbuf to the interface, one pbuf at a
|
||||
// time. The size of the data in each pbuf is kept in the ->len
|
||||
// variable.
|
||||
for(i = 0; i < q->len; i += 2) |
||||
{ |
||||
RXTXREG = *ptr++; |
||||
} |
||||
#if (CS8900_STATS > 0) |
||||
((struct cs8900if *)netif->state)->sentbytes += q->len; |
||||
#endif |
||||
#if LWIP_SNMP > 0 |
||||
snmp_add_ifoutoctets(p->tot_len); |
||||
#endif |
||||
#if (CS8900_STATS > 0) |
||||
((struct cs8900if *)netif->state)->sentpackets++; |
||||
#endif |
||||
} |
||||
} |
||||
else |
||||
{ |
||||
// { not ready to transmit!? }
|
||||
#if LWIP_SNMP > 0 |
||||
snmp_inc_ifoutdiscards(); |
||||
#endif |
||||
} |
||||
return ERR_OK; |
||||
} |
||||
|
||||
/**
|
||||
* Move a received packet from the cs8900 into a new pbuf. |
||||
* |
||||
* Must be called after reading an ISQ event containing the |
||||
* "Receiver Event" register, before reading new ISQ events. |
||||
* |
||||
* This function copies a frame from the CS8900A. |
||||
* It is designed failsafe: |
||||
* - It does not assume a frame is actually present. |
||||
* - It checks for non-zero length |
||||
* - It does not overflow the frame buffer |
||||
*/ |
||||
static struct pbuf *cs8900_input(struct netif *netif) |
||||
{ |
||||
struct pbuf *p = NULL, *q = NULL; |
||||
u16_t len = 0; |
||||
u16_t event_type; |
||||
u16_t i; |
||||
u16_t *ptr = NULL; |
||||
|
||||
// read RxStatus
|
||||
event_type = RXTXREG; |
||||
|
||||
// correctly received frame, either broadcast or individual address?
|
||||
// TODO: maybe defer these conditions to cs8900_input()
|
||||
if ((event_type & 0x0100U/*RxOK*/) && (event_type & 0x0c00U/*Broadcast | Individual*/)) |
||||
{ |
||||
#if LWIP_SNMP > 0 |
||||
// update number of received MAC-unicast and non-MAC-unicast packets
|
||||
if (event_type & 0x0400U/*Individual*/) |
||||
{ |
||||
snmp_inc_ifinucastpkts(); |
||||
} |
||||
else |
||||
{ |
||||
snmp_inc_ifinnucastpkts(); |
||||
} |
||||
#endif |
||||
event_type = 0;
|
||||
// read RxLength
|
||||
len = RXTXREG; |
||||
DEBUGF(NETIF_DEBUG, ("cs8900_input: packet len %u\n", len)); |
||||
#if LWIP_SNMP > 0 |
||||
snmp_add_ifinoctets(len); |
||||
#endif |
||||
// positive length?
|
||||
if (len > 0) |
||||
{ |
||||
// allocate a pbuf chain with total length 'len'
|
||||
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); |
||||
if (p != 0) |
||||
{ |
||||
for (q = p; q != 0; q = q->next) |
||||
{ |
||||
DEBUGF(NETIF_DEBUG, ("cs8900_input: pbuf @%p len %u\n", q, q->len)); |
||||
ptr = q->payload; |
||||
// TODO: CHECK: what if q->len is odd? we don't use the last byte?
|
||||
for (i = 0; i < (q->len + 1) / 2; i++) |
||||
{ |
||||
*ptr = RXTXREG; |
||||
ptr++; |
||||
} |
||||
} |
||||
} |
||||
// could not allocate a pbuf
|
||||
else |
||||
{ |
||||
// skip received frame
|
||||
// TODO: maybe do not skip the frame at this point in time?
|
||||
PACKETPP = CS_PP_RXCFG; |
||||
PPDATA = (0x0003U | 0x0100U/*RxOKiE*/ | 0x0040U/*Skip_1*/); |
||||
#if (CS8900_STATS > 0) |
||||
((struct cs8900if *)netif->state)->dropped++; |
||||
#endif |
||||
#if LWIP_SNMP > 0 |
||||
snmp_inc_ifindiscards(); |
||||
#endif |
||||
len = 0; |
||||
} |
||||
} |
||||
// length was zero
|
||||
else |
||||
{ |
||||
} |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
|
||||
/**
|
||||
* To be called when the cs8900a needs service. Does |
||||
* not assume the cs8900a needs service. Does test the |
||||
* cs8900a whether it needs service.
|
||||
* |
||||
* As such, may be used robustly called as a deferred |
||||
* (or "late") interrupt handler, or may be called in |
||||
* a loop to implement polling, or both. |
||||
* |
||||
* Use cs8900if_service() from your application instead |
||||
* of this function.
|
||||
*/ |
||||
|
||||
static void cs8900_service(struct netif *netif) |
||||
{ |
||||
// amount of ISQ's to handle (> 0) in one cs8900_service() call
|
||||
unsigned char events2service = 1; |
||||
// NOTES:
|
||||
// static, so only initialized to zero at program start.
|
||||
// irq_status will always hold the last ISQ event register that
|
||||
// still needs service. As such, we may leave this function if
|
||||
// we encounter an event we cannot service yet, and return later
|
||||
// to try to service it.
|
||||
static u16_t irq_status = 0x0000U; |
||||
|
||||
// The "cs8900_needs_service" flag indicates whether any events
|
||||
// still need to be serviced.
|
||||
// clear flag here.
|
||||
// a receive interrupt can, *concurrently with this function*,
|
||||
// set this flag on new ISQ event occurences.
|
||||
// we will re-evaluate the correct setting of this flag at
|
||||
// function exit (below).
|
||||
((struct cs8900if *)netif->state)->needs_service = 0; |
||||
#ifdef LED_NEED_SERVICE |
||||
leds_off(LED_NEED_SERVICE); |
||||
#endif |
||||
// no unhandled irq_status left?
|
||||
if (irq_status == 0x0000U) |
||||
{ |
||||
// read ISQ register
|
||||
irq_status = ISQ; |
||||
} |
||||
// ISQ interrupt event, and allowed to service in this loop?
|
||||
while ((irq_status != 0x0000U) && (events2service-- > 0)) |
||||
{ |
||||
// investigate event
|
||||
if ((irq_status & 0x003fU) == 0x0004U/*Receiver Event*/) |
||||
{ |
||||
// correctly received frame, either broadcast or individual address
|
||||
// TODO: think where these checks should appear: here or in cs8900_input()
|
||||
if ((irq_status & 0x0100U/*RxOK*/) && (irq_status & 0x0c00U/*Broadcast | Individual*/)) |
||||
{ |
||||
// read the frame from the cs8900a
|
||||
cs8900if_input(netif); |
||||
} |
||||
else |
||||
{ |
||||
// skip this frame
|
||||
PACKETPP = CS_PP_RXCFG; |
||||
PPDATA |= 0x0040U/*Skip_1*/; |
||||
#if (CS8900_STATS > 0) |
||||
((struct cs8900if *)netif->state)->dropped++; |
||||
#endif |
||||
} |
||||
} |
||||
#if (CS8900_STATS > 0) |
||||
else if ((irq_status & 0x003fU) == 0x0010U/*RxMISS Event*/) |
||||
{ |
||||
((struct cs8900if *)netif->state)->missed += (irq_status >> 6); |
||||
} |
||||
else if ((irq_status & 0x003fU) == 0x0012U/*TxCOL Event*/) |
||||
{ |
||||
((struct cs8900if *)netif->state)->collisions += (irq_status >> 6); |
||||
} |
||||
#endif |
||||
// read ISQ register
|
||||
irq_status = ISQ; |
||||
} |
||||
|
||||
// we did not deplete the ISQ?
|
||||
if (irq_status != 0x0000U) |
||||
{ |
||||
// the cs8900a still needs service
|
||||
((struct cs8900if *)netif->state)->needs_service = 1; |
||||
#ifdef LED_NEED_SERVICE |
||||
leds_on(LED_NEED_SERVICE); |
||||
#endif |
||||
} |
||||
#if (CS8900_STATS > 1) |
||||
// read RxMiss Counter (zeroes itself upon read)
|
||||
PACKETPP = CS_PP_RXMISS; |
||||
((struct cs8900if *)netif->state)->missed += (PPDATA >> 6); |
||||
// read RxCol Counter (zeroes itself upon read)
|
||||
PACKETPP = CS_PP_TXCOL; |
||||
((struct cs8900if *)netif->state)->collisions += (PPDATA >> 6); |
||||
#endif |
||||
} |
||||
|
||||
/**
|
||||
* Service the CS8900. |
||||
* |
||||
* Can be called in a polling manner, or only after the CS8900 has raised |
||||
* an interrupt request. |
||||
* |
||||
* @param netif The lwIP network interface data structure belonging to this device. |
||||
* |
||||
*/ |
||||
void cs8900if_service(struct netif *netif) |
||||
{ |
||||
// is there a reason to call the service routine?
|
||||
if ((((struct cs8900if *)netif->state)->needs_service) || |
||||
(((struct cs8900if *)netif->state)->use_polling)) |
||||
{ |
||||
cs8900_service(netif); |
||||
} |
||||
} |
||||
|
||||
/**
|
||||
* Writing an IP packet (to be transmitted) to the CS8900. |
||||
* |
||||
* Before writing a frame to the CS8900, the ARP module is asked to resolve the |
||||
* Ethernet MAC address. The ARP module might undertake actions to resolve the |
||||
* address first, and queue this packet for later transmission. |
||||
* |
||||
* @param netif The lwIP network interface data structure belonging to this device. |
||||
* @param p pbuf to be transmitted (or the first pbuf of a chained list of pbufs). |
||||
* @param ipaddr destination IP address. |
||||
* |
||||
* @internal It uses the function cs8900_input() that should handle the actual |
||||
* reception of bytes from the network interface. |
||||
* |
||||
*/ |
||||
err_t cs8900if_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) |
||||
{ |
||||
struct cs8900if *cs8900if = netif->state; |
||||
p = etharp_output(netif, ipaddr, p); |
||||
/* network hardware address obtained? */ |
||||
if (p != NULL) |
||||
{ |
||||
/* send out the packet */ |
||||
cs8900_output(netif, p); |
||||
p = NULL; |
||||
} |
||||
// { p == NULL }
|
||||
else |
||||
{ |
||||
/* we cannot tell if the packet was sent, the packet could have been queued */ |
||||
/* on an ARP entry that was already pending. */ |
||||
} |
||||
return ERR_OK; |
||||
} |
||||
/**
|
||||
* Read a received packet from the CS8900. |
||||
* |
||||
* This function should be called when a packet is received by the CS8900 |
||||
* and is fully available to read. It moves the received packet to a pbuf |
||||
* which is forwarded to the IP network layer or ARP module. It transmits |
||||
* a resulting ARP reply or queued packet. |
||||
* |
||||
* @param netif The lwIP network interface to read from. |
||||
* |
||||
* @internal Uses cs8900_input() to move the packet from the CS8900 to a |
||||
* newly allocated pbuf. |
||||
* |
||||
*/ |
||||
void cs8900if_input(struct netif *netif) |
||||
{ |
||||
struct cs8900if *cs8900if = netif->state; |
||||
struct eth_hdr *ethhdr = NULL; |
||||
struct pbuf *p = NULL, *q = NULL; |
||||
|
||||
/* move received packet into a new pbuf */ |
||||
p = cs8900_input(netif); |
||||
/* no packet could be read */ |
||||
if (p == NULL) { |
||||
/* silently ignore this */ |
||||
return; |
||||
} |
||||
/* points to packet payload, which starts with an Ethernet header */ |
||||
ethhdr = p->payload; |
||||
|
||||
q = NULL; |
||||
switch(htons(ethhdr->type)) { |
||||
/* IP packet? */ |
||||
case ETHTYPE_IP: |
||||
/* update ARP table, obtain first queued packet */ |
||||
q = etharp_ip_input(netif, p); |
||||
/* skip Ethernet header */ |
||||
pbuf_header(p, -14); |
||||
/* pass to network layer */ |
||||
netif->input(p, netif); |
||||
break; |
||||
/* ARP packet? */ |
||||
case ETHTYPE_ARP: |
||||
/* pass p to ARP module, get ARP reply or ARP queued packet */ |
||||
q = etharp_arp_input(netif, (struct eth_addr *)&netif->hwaddr, p); |
||||
break; |
||||
/* unsupported Ethernet packet type */ |
||||
default: |
||||
/* free pbuf */ |
||||
pbuf_free(p); |
||||
p = NULL; |
||||
break; |
||||
} |
||||
/* send out the ARP reply or ARP queued packet */ |
||||
if (q != NULL) { |
||||
/* q pbuf has been succesfully sent? */ |
||||
if (cs8900_output(netif, q) == ERR_OK) |
||||
{ |
||||
pbuf_free(q); |
||||
q = NULL; |
||||
} |
||||
else |
||||
{ |
||||
/* TODO: re-queue packet in the ARP cache here (?) */ |
||||
pbuf_free(q); |
||||
q = NULL; |
||||
} |
||||
} |
||||
} |
||||
/**
|
||||
* Initialize the CS8900 Ethernet MAC/PHY device driver. |
||||
* |
||||
* @param netif The lwIP network interface data structure belonging to this device. |
||||
* |
||||
*/ |
||||
void cs8900if_init(struct netif *netif) |
||||
{ |
||||
struct cs8900if *cs8900if; |
||||
|
||||
cs8900if = mem_malloc(sizeof(struct cs8900if)); |
||||
if(cs8900if == NULL) return; |
||||
|
||||
// initialize lwip network interface
|
||||
netif->name[0] = IFNAME0; |
||||
netif->name[1] = IFNAME1; |
||||
netif->output = cs8900if_output; |
||||
netif->linkoutput = cs8900_output; |
||||
|
||||
// initialize cs8900 specific interface structure
|
||||
netif->state = cs8900if; |
||||
|
||||
// initially assume no ISQ event
|
||||
cs8900if->needs_service = 0; |
||||
// set to 1 if polling method is used
|
||||
cs8900if->use_polling = 0; |
||||
|
||||
#if (CS8900_STATS > 0) |
||||
// number of interrupt service routine calls
|
||||
cs8900if->interrupts = 0; |
||||
cs8900if->missed = 0; |
||||
cs8900if->dropped = 0; |
||||
cs8900if->sentpackets = 0; |
||||
cs8900if->sentbytes = 0; |
||||
#endif |
||||
|
||||
// intialize the cs8900a chip
|
||||
cs8900_init(netif); |
||||
} |
||||
|
||||
#if 1 |
||||
/**
|
||||
* Dump an array of bytes inside a UDP message's data field. |
||||
* |
||||
* It is a self-contained function, independent of higher protocol layers or other |
||||
* functions, so it allows you to debug these higher layers, such as lwIP. |
||||
* |
||||
* @param p pointer to an array of bytes, at least with length 'len' |
||||
* @param len number of bytes available at the address pointed to by 'p' |
||||
*/ |
||||
void cs8900_send_debug(unsigned char *p, unsigned int len) |
||||
{ |
||||
int tries = 0, i; |
||||
|
||||
// network interface state
|
||||
extern struct netif *ethif; |
||||
|
||||
// exit if link has failed
|
||||
PACKETPP = CS_PP_LINESTATUS; |
||||
if ((PPDATA & 0x0080U/*LinkOK*/) == 0) return; // TODO: find a correct error code
|
||||
|
||||
// transmit command
|
||||
TXCMD = 0x00C9U; |
||||
// send at least 60 bytes
|
||||
TXLENGTH = (14 + 20 + 8 + len < 60) ? 60 : (14 + 20 + 8 + len); |
||||
|
||||
PACKETPP = CS_PP_BUSSTATUS; |
||||
// not ready for transmission and still within 100 retries?
|
||||
while (((PPDATA & 0x0100U/*Rdy4TxNOW*/) == 0) && (tries++ < 100)) |
||||
{ |
||||
// throw away the last committed received frame
|
||||
PACKETPP = CS_PP_RXCFG; |
||||
PPDATA = (0x0003U | 0x0040U/*Skip_1*/ | 0x0100U/*RxOKiE*/); |
||||
PACKETPP = CS_PP_BUSSTATUS; |
||||
/* cs8900if->dropped++; CHECK: we do not know if we actually will drop a frame here, do we? */
|
||||
} |
||||
// ready to transmit?
|
||||
if((PPDATA & 0x0100U/*Rdy4TxNOW*/) != 0) |
||||
{
|
||||
u16_t data, checksum = 0; |
||||
u32_t udp_checksum = 0; |
||||
|
||||
// destination Ethernet address
|
||||
RXTXREG = 0xa000U;
|
||||
RXTXREG = 0xc524U;
|
||||
RXTXREG = 0x6d72U;
|
||||
// source Ethernet address
|
||||
RXTXREG = htons(((u16_t)ethif->hwaddr[0] << 8U) | (u16_t)ethif->hwaddr[1]);
|
||||
RXTXREG = htons(((u16_t)ethif->hwaddr[2] << 8U) | (u16_t)ethif->hwaddr[3]);
|
||||
RXTXREG = htons(((u16_t)ethif->hwaddr[4] << 8U) | (u16_t)ethif->hwaddr[5]); |
||||
// frame type
|
||||
RXTXREG = htons(0x0800); |
||||
// TOS, version
|
||||
RXTXREG = htons(data = ((0x40 | 0x05) << 8) | 0x00);
|
||||
checksum += data; |
||||
// length
|
||||
RXTXREG = htons(data = 20 + 8 + len);
|
||||
checksum += data; |
||||
// identifier
|
||||
RXTXREG = htons(data = 0);
|
||||
checksum += data; |
||||
// fragment offset
|
||||
RXTXREG = htons(data = 0);
|
||||
checksum += data; |
||||
// TTL, UDP protocol
|
||||
RXTXREG = htons(data = (255U << 8) | 17U);
|
||||
checksum += data; |
||||
|
||||
checksum += (htonl(ethif->ip_addr.addr) & 0xffff0000U) >> 16; |
||||
checksum += (htonl(ethif->ip_addr.addr) & 0x0000ffffU); |
||||
checksum += 0xc0a8U; |
||||
checksum += 0x0001U; |
||||
checksum += 6; // LW: kludge/hack: checksum calculation seems to be wrong somehow
|
||||
// LW: this seems (?) to fix it
|
||||
// checksum
|
||||
RXTXREG = htons(~checksum);
|
||||
|
||||
// source IP
|
||||
RXTXREG = htons((htonl(ethif->ip_addr.addr) & 0xffff0000U) >> 16);
|
||||
// source IP
|
||||
RXTXREG = htons( htonl(ethif->ip_addr.addr) & 0x0000ffffU);
|
||||
// destination IP
|
||||
RXTXREG = htons(0xc0a8U);
|
||||
// destination IP
|
||||
RXTXREG = htons(0x0001U);
|
||||
// source port 3000
|
||||
RXTXREG = htons(3000U);
|
||||
// destination port 3000
|
||||
RXTXREG = htons(3000U);
|
||||
// UDP length
|
||||
RXTXREG = htons(len);
|
||||
// UDP checksum (not present)
|
||||
|
||||
udp_checksum = (htonl(ethif->ip_addr.addr) & 0xffff0000U) >> 16; |
||||
udp_checksum += (htonl(ethif->ip_addr.addr) & 0x0000ffffU); |
||||
udp_checksum += 0xc0a8U; |
||||
udp_checksum += 0x0001U; |
||||
udp_checksum += 0x0011U; |
||||
udp_checksum += (8 + len); |
||||
udp_checksum += 3000; |
||||
udp_checksum += 3000; |
||||
udp_checksum += (8 + len); |
||||
udp_checksum += cs8900_chksum(p, len); |
||||
while(udp_checksum >> 16) { |
||||
udp_checksum = (udp_checksum & 0xffffUL) + (udp_checksum >> 16); |
||||
}
|
||||
|
||||
RXTXREG = htons(~(udp_checksum & 0xffff)); |
||||
// UDP data
|
||||
for (i = 0; i < len; i += 2) |
||||
{ |
||||
RXTXREG = htons((p[i] << 8) | p[i + 1]); |
||||
}
|
||||
// pad to 60 bytes
|
||||
while (i < 60) |
||||
{ |
||||
RXTXREG = 0; |
||||
i += 2; |
||||
} |
||||
} |
||||
} |
||||
|
||||
static u32_t cs8900_chksum(void *dataptr, int len) |
||||
{ |
||||
u32_t acc = 0; |
||||
u16_t *ptr = (u16_t *)dataptr; |
||||
|
||||
for(acc = 0; len > 1; len -= 2) { |
||||
acc += *ptr; |
||||
ptr++; |
||||
} |
||||
/* add up any odd byte */ |
||||
if(len == 1) { |
||||
acc += htons((u16_t)((*(u8_t *)ptr) & 0xffU) << 8); |
||||
} |
||||
return acc; |
||||
} |
||||
|
||||
#endif |
||||
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Swedish Institute of Computer Science. |
||||
* All rights reserved.
|
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* |
||||
* This file is part of the lwIP TCP/IP stack. |
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se> |
||||
* |
||||
* $Id: perf.c,v 1.1 2003/01/18 18:21:57 jani Exp $ |
||||
*/ |
||||
|
||||
#include "arch/perf.h" |
||||
|
||||
void |
||||
perf_init(char *fname) |
||||
{ |
||||
if (fname); // LEON: prevent warning
|
||||
} |
||||
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 2001, Swedish Institute of Computer Science. |
||||
* All rights reserved.
|
||||
* |
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* |
||||
* This file is part of the lwIP TCP/IP stack. |
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se> |
||||
* |
||||
* $Id: sys_arch.c,v 1.1 2003/01/18 18:21:57 jani Exp $ |
||||
*/ |
||||
|
||||
#include "lwip/def.h" |
||||
#include "lwip/sys.h" |
||||
#include "lwip/mem.h" |
||||
|
||||
//#include "timers.h"
|
||||
|
||||
static struct sys_timeouts timeouts; |
||||
|
||||
/*-----------------------------------------------------------------------------------*/ |
||||
sys_mbox_t |
||||
sys_mbox_new(void) |
||||
{ |
||||
return SYS_MBOX_NULL; |
||||
} |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
void |
||||
sys_mbox_free(sys_mbox_t mbox) |
||||
{ |
||||
if (mbox); // LEON: prevent warning
|
||||
return; |
||||
} |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
void |
||||
sys_mbox_post(sys_mbox_t mbox, void *data) |
||||
{ |
||||
if (mbox); // LEON: prevent warning
|
||||
if (data); // LEON: prevent warning
|
||||
return; |
||||
} |
||||
|
||||
u16_t |
||||
sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u16_t timeout) |
||||
{ |
||||
if (mbox); // LEON: prevent warning
|
||||
if (msg); // LEON: prevent warning
|
||||
if (timeout); // LEON: prevent warning
|
||||
return 0; |
||||
} |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
sys_sem_t |
||||
sys_sem_new(u8_t count) |
||||
{ |
||||
if (count); |
||||
return 0; |
||||
} |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
u16_t |
||||
sys_arch_sem_wait(sys_sem_t sem, u16_t timeout) |
||||
{ |
||||
if (sem); |
||||
return 0; |
||||
} |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
void |
||||
sys_sem_signal(sys_sem_t sem) |
||||
{ |
||||
if (sem); |
||||
return; |
||||
} |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
void |
||||
sys_sem_free(sys_sem_t sem) |
||||
{ |
||||
if (sem); |
||||
return; |
||||
} |
||||
|
||||
void |
||||
sys_init(void) |
||||
{ |
||||
timeouts.next = NULL; |
||||
return; |
||||
} |
||||
|
||||
struct sys_timeouts * |
||||
sys_arch_timeouts(void) |
||||
{ |
||||
return &timeouts; |
||||
} |
||||
|
||||
u8_t
|
||||
sys_timeout_u32_t(u32_t msecs, sys_timeout_handler h, void *data) // LEON: arg 1 was unsigned int
|
||||
{ |
||||
return 0; |
||||
// WAS: return timer_obtain(msecs, h, data);
|
||||
// RE-ENABLE IF DHCP_TIMER_CALLBACKS
|
||||
#if DHCP_TIMER_CALLBACKS |
||||
#error DHCP_TIMER_CALLBACKS not supported! |
||||
#endif |
||||
} |
||||
|
||||
void |
||||
sys_thread_new(void (* function)(void *arg), void *arg) |
||||
{ |
||||
if (arg); // LW
|
||||
} |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
void |
||||
sys_main(void) |
||||
{ |
||||
} |
||||
/*-----------------------------------------------------------------------------------*/ |
||||
Loading…
Reference in new issue