Update the driver in "ti_c6711", using QDMA of C6000 DSP now, which is much faster. [2005.11.07 by Ming]

This commit is contained in:
ming 2005-11-07 00:50:49 +00:00
parent 8b6c9a5035
commit e17ac1ad2b
7 changed files with 499 additions and 400 deletions

View File

@ -18,7 +18,7 @@ v2pro/ - Architectural files for the Xilinx Virtex-II PRO device with
coldfire/ - Architectural files for Motorola Coldfire 5272 CPU running
under Nucleus OS. Supports DMA and ISRs in ethernet driver.
ti_c6711/ - Architectural files for TI TMS320C6711 DSP running under uC/OS-II.
ti_c6711/ - Architectural files for TI TMS320C6000 DSP running under uC/OS-II.
Supports lwIP Raw API only.
It's done with an 10/100M ethernet daughtercard.
[more info at https://sourceforge.net/projects/ucos-lwip-c6x/]

View File

@ -36,13 +36,13 @@ following options should be set:
4. #define LWIP_TASK_MAX 5 (in "sys_arch.h" )
#define LWIP_START_PRIO 5 (in "sys_arch.h" )
#define LWIP_START_PRIO 10 (in "sys_arch.h" )
#define TCPIP_THREAD_PRIO 5 (in "lwipopts.h" )
That is, 5 lwIP threads were allowed, and default TCPIP_THREAD used priority 5.
The default TCPIP_THREAD used priority 5.
So, user defined lwIP thread should have its priority between 6 ~ 9.
And, 5 lwIP threads were allowed, user defined lwIP thread should have its priority between 10 ~ 14.
5. #define SYS_LIGHTWEIGHT_PROT 1 (in "lwipopts.h" )

View File

@ -14,17 +14,57 @@
#include "lwip/netif.h"
static err_t ne2k_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr);
static void ne2k_input(struct netif *netif);
err_t ne2k_init(struct netif *netif);
#define MIN_PACKET_SIZE 60 /* smallest legal size packet, no fcs */
#define MAX_PACKET_SIZE 1514 /* largest legal size packet, no fcs */
/*----------------------------------------
* Register header for NE2000 chip
*----------------------------------------*/
#define DELAY 0x590b2 //0.5s test by ming
#define DELAY_2S 0xbf000 //2s test
#define DELAY_MS 0x38F4 //20ms test
/**
* Driver functions.
*/
err_t ne2k_init(struct netif *netif);
static void low_level_init(struct netif * netif);
static void arp_timer(void *arg);
static err_t ne2k_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr);
static err_t low_level_output(struct netif * netif,struct pbuf *p);
u16_t write_AX88796(u8_t * buf, u16_t remote_Addr, u16_t Count);
static void ne2k_input(struct netif *netif);
static struct pbuf * low_level_input(struct netif *netif);
u16_t read_AX88796(u8_t * buf, u16_t remote_Addr, u16_t Count);
/*----------------------------------------
* Register header of C6x DSP
*----------------------------------------*/
#define EMIF_CE2 0x01800010
/* Define QDMA Memory Mapped Registers */
#define QDMA_OPT 0x02000000 /* Address of QDMA options register */
#define QDMA_SRC 0x02000004 /* Address of QDMA SRC address register */
#define QDMA_CNT 0x02000008 /* Address of QDMA counts register */
#define QDMA_DST 0x0200000C /* Address of QDMA DST address register */
#define QDMA_IDX 0x02000010 /* Address of QDMA index register */
/* Define QDMA Pseudo Registers */
#define QDMA_S_OPT 0x02000020 /* Address of QDMA options register */
#define QDMA_S_SRC 0x02000024 /* Address of QDMA SRC address register */
#define QDMA_S_CNT 0x02000028 /* Address of QDMA counts register */
#define QDMA_S_DST 0x0200002C /* Address of QDMA DST address register */
#define QDMA_S_IDX 0x02000030 /* Address of QDMA index register */
/*----------------------------------------
* Register header of NE2000 chip
*----------------------------------------*/
#define Base_ADDR 0xA0000200 ///CE2 space of DSK is 0xA0000000
// and ethernet chip is at 0x200 by default
@ -84,14 +124,22 @@ err_t ne2k_init(struct netif *netif);
#define EN_PAGE0 0x00 /* Select page chip registers */
#define EN_PAGE1 0x40 /* using the two high-order bits */
//---------------------------------
// Values for Ring-Buffer setting
#define TX_PAGES 6
//---------------------------------
#define NE_START_PG 0x40 /* First page of TX buffer */
#define TX_START_PG NE_START_PG //0x40
#define NE_STOP_PG 0x80 /* Last page + 1 of RX Ring */
#define RX_STOP_PG NE_STOP_PG //0x80
#define TX_PAGES 6
#define TX_START_PG NE_START_PG //0x40
#define RX_START_PG NE_START_PG + TX_PAGES //0x46
#define RX_CURR_PG RX_START_PG + 1 //0x47
#define RX_STOP_PG NE_STOP_PG //0x80
/* Bits in EN0_ISR - Interrupt status register (RD WR) */

View File

@ -19,24 +19,69 @@
#include "netif/ne2kif.h"
/* define this to use QDMA, which is much faster! */
#define QDMA_Enabled
/* Define those to better describe your network interface. */
#define IFNAME0 'e'
#define IFNAME1 't'
#define DELAY 0x590b2 //0.5s test by ming
#define DELAY_2S 0xbf000 //2s test
#define DELAY_MS 0x38F4 //20ms test
struct ne2k_if {
struct eth_addr *ethaddr; //MAC Address
};
struct netif *ne2k_if_netif;
static void low_level_init(struct netif * netif);
static err_t low_level_output(struct netif * netif,struct pbuf *p);
static struct pbuf * low_level_input(struct netif *netif);
/*----------------------------------------------------------------------------------------
****************************************************************************************
----------------------------------------------------------------------------------------*/
/*
* ethernetif_init():
*
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
*
*/
err_t ne2k_init(struct netif *netif)
{
struct ne2k_if *ne2k_if;
ne2k_if = mem_malloc(sizeof(struct ne2k_if));//MAC Address
if (ne2k_if == NULL)
{
LWIP_DEBUGF(NETIF_DEBUG,("ne2k_init: out of memory!\n"));
return ERR_MEM;
}
netif->state = ne2k_if;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
netif->output = ne2k_output;
netif->linkoutput = low_level_output;
ne2k_if->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
low_level_init(netif);
etharp_init();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
return ERR_OK;
}
/**
* arp_timer.
*/
static void arp_timer(void *arg)
{
etharp_tmr();
sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
}
/**
* Initialize the ne2k ethernet chip, resetting the interface and getting the ethernet
@ -45,7 +90,6 @@ static struct pbuf * low_level_input(struct netif *netif);
static void low_level_init(struct netif * netif)
{
u16_t i;
struct ne2k_if *ne2k_if;
ne2k_if = netif->state;
@ -56,8 +100,10 @@ static void low_level_init(struct netif * netif)
netif->flags = NETIF_FLAG_BROADCAST;
// ---------- start -------------
*(u32_t *)EMIF_CE2 = 0x11D4C714; // Set CE2 to 16bits mode,
// AX88796 required no less than 160ns period
i = EN_RESET;//this instruction let NE2K chip soft reset
i = EN_RESET; //this instruction let NE2K chip soft reset
for (i=0;i<DELAY_MS;i++); //wait
@ -85,8 +131,7 @@ static void low_level_init(struct netif * netif)
EN0_IMR = (u8_t) 0x00; /* Disable all Interrupt */
EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
EN1_CURR = (u8_t) 0x47;
/* RX_CURR_PG; 47 (keep curr=boundary+1 means no new packet) */
EN1_CURR = (u8_t) 0x47; /* keep curr=boundary+1 means no new packet */
EN1_PAR0 = (u8_t)0x12;// MAC_addr.addr[0]; //×Ô¶¨ÒåµÄmacµØÖ·
EN1_PAR1 = (u8_t)0x34;// MAC_addr.addr[1];
@ -115,13 +160,12 @@ static void low_level_init(struct netif * netif)
EN1_MAR6 = (u8_t) 0x00;
EN1_MAR7 = (u8_t) 0x00;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP); /* 00001010B: PS1 PS0 RD2 RD1 RD0 TXP STA STP */
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
EN0_IMR = (u8_t) (ENISR_OVER + ENISR_RX + ENISR_RX_ERR);
//(ENISR_OVER + ENISR_RX + ENISR_TX + ENISR_TX_ERR);
EN0_TXCR = (u8_t) 0xE0; //ENTXCR_TXCONFIG; //TCR
EN0_RXCR = (u8_t) 0xCC; //without Multicast //0xcc //RCR
EN0_TXCR = (u8_t) 0x00; //E0 //TCR
EN0_RXCR = (u8_t) 0x44; //CC //RCR
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
@ -131,242 +175,9 @@ static void low_level_init(struct netif * netif)
}
/*
* low_level_output():
*
* Should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
*/
static err_t low_level_output(struct netif * netif, struct pbuf *p)
{
struct pbuf *q;
u16_t padLength,packetLength,Count,loop,rd_tmp;
u8_t *buf,flag1=0 ;
/*
* Set up to transfer the packet contents to the NIC RAM.
*/
padLength = 0;
packetLength = p->tot_len - ETH_PAD_SIZE; //05 01 millin
if ((packetLength) < 64)
{
padLength = 64 - (packetLength);
packetLength = 64;
}
/* Wait for other transmit */
while ( EN_CMD & EN_TRANS );
/* We should already be in page 0, but to be safe... */
EN_CMD = (u8_t) (EN_PAGE0 + EN_START + EN_NODMA);
EN0_IMR = (u8_t) (ENISR_OVER);
//(ENISR_OVER + ENISR_TX + ENISR_TX_ERR);
// turn off RX int
EN0_ISR = (u8_t) ENISR_RDC; // clear the RDC bit
/* Now the normal output. */
EN0_RCNTLO = (u8_t) (packetLength & 0xff);
EN0_RCNTHI = (u8_t) ((packetLength >> 8) & 0xff);
EN0_RSARLO = (u8_t) ((TX_START_PG<<8) & 0xFF);
EN0_RSARHI = (u8_t) (TX_START_PG & 0xFF);
EN_CMD = (u8_t) (EN_RWRITE + EN_START + EN_PAGE0);
/*
* Write packet to ring buffers.
*/
for(q = p; q != NULL; q = q->next) {
/* 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. */
Count = q->len;
buf = q->payload;
if (q == p){
buf += ETH_PAD_SIZE;
Count -= ETH_PAD_SIZE;//Pad in Eth_hdr struct
}
if ( (Count & 0x0001) ) flag1 = 1;
Count = Count>>1;
for (loop=0;loop < Count ;loop++){
rd_tmp = (*buf++) + ((*buf++) << 8 );
EN_DATA = (u16_t) rd_tmp;
}
if (flag1 == 1) *(unsigned char *)(Base_ADDR+0x10) = *buf++;
}
while(padLength-- > 0){
*(unsigned char *)(Base_ADDR+0x10) = (u8_t)0x00;
// Write padding for undersized packets
}
EN0_ISR = (u8_t) ENISR_RDC; // clear the RDC bit
/* Just send it, and does not check */
EN0_TCNTLO = (u8_t) (packetLength& 0xff);
EN0_TCNTHI = (u8_t) (packetLength>> 8);
EN0_TPSR = (u8_t) TX_START_PG;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_TRANS + EN_START);
EN0_IMR = (u8_t) (ENISR_OVER + ENISR_RX + ENISR_RX_ERR);
//(ENISR_OVER + ENISR_RX + ENISR_TX + ENISR_TX_ERR);
#if LINK_STATS
lwip_stats.link.xmit++;
#endif /* LINK_STATS */
return ERR_OK;
}
/*
* low_level_input():
*
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
*/
static struct pbuf *
low_level_input(struct netif *netif)
{
struct ne2k_if *ne2k_if = netif->state;
u16_t packetLength,len,Count,loop,rd_tmp;
u8_t PDHeader[4]; // Temp storage for ethernet headers//18
struct pbuf * p;
struct pbuf * q;
u8_t *payload,*buf,flag1=0;
u8_t curr,this_frame,next_frame;
EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_START);
curr = (u8_t) EN1_CURR;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
this_frame = (u8_t) EN0_BOUNDARY + 1;//millin + 1
if (this_frame >= RX_STOP_PG)
this_frame = RX_START_PG;
EN0_RCNTLO = (u8_t) 4;
EN0_RCNTHI = (u8_t) 0;
EN0_RSARLO = (u8_t) 0; /* See controller manual , use send packet command */
EN0_RSARHI = (u8_t) this_frame; /* See controller manual , use send packet command */
EN_CMD = (u8_t) (EN_PAGE0 + EN_RREAD + EN_START);
//get the first 4 bytes from nic
Count = 2;
buf = PDHeader;
while(Count--) {
rd_tmp = EN_DATA ;
*buf++ = (u8_t)(rd_tmp & 0x00ff) ;
*buf++ = (u8_t)(rd_tmp >> 8) ;
}
EN0_ISR = (u8_t) ENISR_RDC; /* clear the RDC bit */
// Store real length, set len to packet length - header
packetLength = ((unsigned) PDHeader[2] | (PDHeader[3] << 8 ));
next_frame = (u8_t) (this_frame + 1 + (packetLength >> 8));
packetLength -= 4;
if ((PDHeader[1] != next_frame)
&& (PDHeader[1] != next_frame + 1)
&& (PDHeader[1] != next_frame - (RX_STOP_PG - RX_START_PG))
&& (PDHeader[1] != next_frame + 1 - (RX_STOP_PG - RX_START_PG)))
{
EN0_BOUNDARY = (u8_t) (curr - 1);
//puts("Bad frame!\n");
return NULL;
}
if (packetLength > MAX_PACKET_SIZE || packetLength < MIN_PACKET_SIZE)
{
next_frame = PDHeader[1];
EN0_BOUNDARY = (u8_t) (next_frame-1);
//printf("Bogus Packet Size \n");
return NULL;
}
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
EN0_RCNTLO = (u8_t) (packetLength & 0xff);
EN0_RCNTHI = (u8_t) (packetLength >> 8);
EN0_RSARLO = (u8_t) 4; /* See controller manual , use send packet command */
EN0_RSARHI = (u8_t) this_frame; /* See controller manual , use send packet command */
EN_CMD = (u8_t) (EN_PAGE0 + EN_RREAD + EN_START);
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc(PBUF_RAW, packetLength+ETH_PAD_SIZE, PBUF_POOL); /* length of buf */
// change from PBUF_LINK
if(p != NULL) {
/* We iterate over the pbuf chain until we have read the entire
packet into the pbuf. */
for(q = p; q != NULL; q= q->next){
/* Read enough bytes to fill this pbuf in the chain. The
avaliable data in the pbuf is given by the q->len
variable. */
payload = q->payload;
len = q->len;
if (q == p){ // if first buf...
payload += ETH_PAD_SIZE;
len -= ETH_PAD_SIZE;//Pad in Eth_hdr struct
}
Count = len;
buf = payload;
if ( (Count & 0x0001) ) flag1 = 1;
Count = Count>>1;
for(loop=0;loop < Count;loop++) {
rd_tmp = EN_DATA ;
*buf++ = (u8_t)(rd_tmp & 0x00ff) ;
*buf++ = (u8_t)(rd_tmp >> 8) ;
}
if ( flag1==1 ) *buf++ = *(unsigned char *)(Base_ADDR+0x10) ;
#if LINK_STATS
lwip_stats.link.recv++;
#endif /* LINK_STATS */
}//for
} else { // p == NULL
/* no more PBUF resource, Discard packet in buffer. */
Count = packetLength;
if ( (Count & 0x0001) ) flag1 = 1; Count = Count>>1;
for(loop=0;loop < Count;loop++) rd_tmp = EN_DATA;
if ( flag1==1 ) rd_tmp = *(unsigned char *)(Base_ADDR+0x10);
#if LINK_STATS
lwip_stats.link.memerr++;
lwip_stats.link.drop++;
#endif /* LINK_STATS */
}
next_frame = PDHeader[1];
EN0_BOUNDARY = (u8_t) (next_frame-1);
EN0_ISR = (u8_t) ENISR_RDC;
return p;
}
/*----------------------------------------------------------------------------------------
****************************************************************************************
----------------------------------------------------------------------------------------*/
/*
* ethernetif_output():
@ -384,6 +195,116 @@ ne2k_output(struct netif *netif, struct pbuf *p,
return etharp_output(netif, ipaddr, p);
}
/*
* low_level_output():
*
* Should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
*/
static err_t low_level_output(struct netif * netif, struct pbuf *p)
{
struct pbuf *q;
u16_t packetLength,remote_Addr,Count;
u8_t *buf;
packetLength = p->tot_len - ETH_PAD_SIZE; //05 01 millin
if ((packetLength) < 64) packetLength = 64; //add pad by the AX88796 automatically
// turn off RX int
EN0_IMR = (u8_t) (ENISR_OVER);
/* We should already be in page 0, but to be safe... */
EN_CMD = (u8_t) (EN_PAGE0 + EN_START + EN_NODMA);
// clear the RDC bit
EN0_ISR = (u8_t) ENISR_RDC;
remote_Addr = (u16_t)(TX_START_PG<<8);
/*
* Write packet to ring buffers.
*/
for(q = p; q != NULL; q = q->next) {
/* 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. */
Count = q->len;
buf = q->payload;
if (q == p){
buf += ETH_PAD_SIZE;
Count -= ETH_PAD_SIZE;//Pad in Eth_hdr struct
}
// Write data to AX88796
remote_Addr = write_AX88796(buf, remote_Addr, Count);
} //for
/* Just send it, and does not check */
while (EN_CMD & EN_TRANS);
EN0_TPSR = (u8_t) TX_START_PG;
EN0_TCNTLO = (u8_t) (packetLength & 0xff);
EN0_TCNTHI = (u8_t) (packetLength >> 8);
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_TRANS + EN_START);
EN0_IMR = (u8_t) (ENISR_OVER + ENISR_RX + ENISR_RX_ERR);
#if LINK_STATS
lwip_stats.link.xmit++;
#endif /* LINK_STATS */
return ERR_OK;
}
/**
* write_AX88796.
*/
u16_t write_AX88796(u8_t * buf, u16_t remote_Addr, u16_t Count)
{
#ifndef QDMA_Enabled
u16_t loop;
#endif
/* AX88796. */
EN0_RCNTLO = (u8_t) ( Count & 0xff);
EN0_RCNTHI = (u8_t) ( Count >> 8);
EN0_RSARLO = (u8_t) ( remote_Addr & 0xff);
EN0_RSARHI = (u8_t) ( remote_Addr >> 8);
EN_CMD = (u8_t) (EN_RWRITE + EN_START + EN_PAGE0);
// Add for next loop...
remote_Addr += Count;
Count = (Count + 1) >> 1; // Turn to 16bits count. <Must add 1 first!>
#ifdef QDMA_Enabled
*(u32_t *)QDMA_SRC = (u32_t) buf;
*(u32_t *)QDMA_DST = (u32_t) &EN_DATA;
*(u32_t *)QDMA_CNT = (u32_t) Count;
*(u32_t *)QDMA_IDX = 0x00000000;
*(u32_t *)QDMA_S_OPT = 0x29000001;
#else
for (loop=0;loop < Count ;loop++){
EN_DATA = *(u16_t *)buf;
buf += 2;
}
#endif //QDMA_Enabled
while ((EN0_ISR & ENISR_RDC) == 0);
EN0_ISR = (u8_t) ENISR_RDC;
return remote_Addr;
}
/*----------------------------------------------------------------------------------------
****************************************************************************************
----------------------------------------------------------------------------------------*/
/*
* ethernetif_input():
@ -402,8 +323,7 @@ ne2k_input(struct netif *netif)
struct pbuf *p;
ne2k_if = netif->state;
//p = low_level_input(ne2k_if);
/* move received packet into a new pbuf */
p = low_level_input(netif);
/* no packet could be read, silently ignore this */
@ -436,55 +356,193 @@ ne2k_input(struct netif *netif)
}
}
/*-----------------------------------------------------------------------------------*/
static void
arp_timer(void *arg)
{
etharp_tmr();
sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)arp_timer, NULL);
}
/*
* ethernetif_init():
* low_level_input():
*
* Should be called at the beginning of the program to set up the
* network interface. It calls the function low_level_init() to do the
* actual setup of the hardware.
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
*/
err_t
ne2k_init(struct netif *netif)
static struct pbuf *
low_level_input(struct netif *netif)
{
struct ne2k_if *ne2k_if;
u16_t packetLength, Count, remote_Addr;
u8_t *buf, PDHeader[4];
u8_t curr, this_frame, next_frame;
struct pbuf *p, *q, *r;
EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_START);
curr = (u8_t) EN1_CURR;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
this_frame = (u8_t) EN0_BOUNDARY + 1;
if (this_frame >= RX_STOP_PG)
this_frame = RX_START_PG;
ne2k_if = mem_malloc(sizeof(struct ne2k_if));//MAC Address
if (ne2k_if == NULL)
{
LWIP_DEBUGF(NETIF_DEBUG,("ne2k_init: out of memory!\n"));
return ERR_MEM;
}
netif->state = ne2k_if;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
netif->output = ne2k_output;
netif->linkoutput = low_level_output;
ne2k_if->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
low_level_init(netif);
etharp_init();
sys_timeout(ARP_TMR_INTERVAL, arp_timer, NULL);
return ERR_OK;
//---------- get the first 4 bytes from AX88796 ---------
(void) read_AX88796(PDHeader, (u16_t)(this_frame<<8), 4);
//----- Store real length, set len to packet length - header ---------
packetLength = ((unsigned) PDHeader[2] | (PDHeader[3] << 8 )) - 4; // minus PDHeader[4]
next_frame = (u8_t) (this_frame + 1 + ((packetLength + 4) >> 8));
// Bad frame!
if ((PDHeader[1] != (u8_t)next_frame) && (PDHeader[1] != (u8_t)(next_frame + 1))
&& (PDHeader[1] != (u8_t)(next_frame - RX_STOP_PG + RX_START_PG))
&& (PDHeader[1] != (u8_t)(next_frame + 1 - RX_STOP_PG + RX_START_PG)))
{
EN0_BOUNDARY = (u8_t) (curr - 1);
return NULL;
}
// Bogus Packet Size
if (packetLength > MAX_PACKET_SIZE || packetLength < MIN_PACKET_SIZE)
{
next_frame = PDHeader[1];
EN0_BOUNDARY = (u8_t) (next_frame-1);
return NULL;
}
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
EN0_ISR = (u8_t) ENISR_RDC; // clear the RDC bit
remote_Addr = (u16_t)((this_frame << 8) + 4);
if ((remote_Addr + packetLength + ETH_PAD_SIZE) > (u16_t)(RX_STOP_PG<<8)) {
p = pbuf_alloc(PBUF_RAW, (u16_t)(RX_STOP_PG<<8) - remote_Addr, PBUF_POOL); /* length of buf */
packetLength -= (u16_t)(RX_STOP_PG<<8) - remote_Addr - ETH_PAD_SIZE;
} else {
p = pbuf_alloc(PBUF_RAW, packetLength+ETH_PAD_SIZE, PBUF_POOL); /* length of buf */
packetLength = 0;
}
if(p != NULL) { /* We iterate over the pbuf chain until we have read the entire packet into the pbuf. */
for(q = p; q != NULL; q= q->next){ /* Read enough bytes to fill this pbuf in the chain. The avaliable data in the pbuf is given by the q->len variable. */
buf = q->payload;
Count = q->len;
if (q == p){ // if it's the first pbuf in chain...
buf += ETH_PAD_SIZE;
Count -= ETH_PAD_SIZE; // pad in Eth_hdr struct
}
remote_Addr = read_AX88796(buf, remote_Addr, Count);
#if LINK_STATS
lwip_stats.link.recv++;
#endif /* LINK_STATS */
} //for(q = p; q != NULL; q= q->next)
} //if(p != NULL)
else
{ // p == NULL
#if LINK_STATS
lwip_stats.link.memerr++;
lwip_stats.link.drop++;
#endif /* LINK_STATS */
}
if (packetLength) // ring buffer cycled
{
remote_Addr = (u16_t)(RX_START_PG << 8);
r = pbuf_alloc(PBUF_RAW, packetLength, PBUF_POOL); /* length of buf */
if(r != NULL) { /* We iterate over the pbuf chain until we have read the entire packet into the pbuf. */
for(q = r; q != NULL; q= q->next){ /* Read enough bytes to fill this pbuf in the chain. The avaliable data in the pbuf is given by the q->len variable. */
buf = q->payload;
Count = q->len;
remote_Addr = read_AX88796(buf, remote_Addr, Count);
} //for
// link pbuf p & r
pbuf_cat(p, r);
}
else // r == NULL
{
#if LINK_STATS
lwip_stats.link.memerr++;
lwip_stats.link.drop++;
#endif
}
} // if (packetLength)
next_frame = PDHeader[1];
EN0_BOUNDARY = (u8_t) (next_frame-1);
return p;
}
/**
* read_AX88796.
*/
u16_t read_AX88796(u8_t * buf, u16_t remote_Addr, u16_t Count)
{
u8_t flagOdd=0;
#ifndef QDMA_Enabled
u16_t loop;
#endif
flagOdd = (Count & 0x0001); // set Flag if Count is odd.
Count -= flagOdd;
EN0_RCNTLO = (u8_t) (Count & 0xff);
EN0_RCNTHI = (u8_t) (Count >> 8);
EN0_RSARLO = (u8_t) (remote_Addr & 0xff);
EN0_RSARHI = (u8_t) (remote_Addr >> 8);
EN_CMD = (u8_t) (EN_PAGE0 + EN_RREAD + EN_START);
/*-----------------------------------------------------------------------------------*/
remote_Addr += Count;
Count = Count>>1;
#ifdef QDMA_Enabled
*(u32_t *)QDMA_SRC = (u32_t) &EN_DATA;
*(u32_t *)QDMA_DST = (u32_t) buf;
*(u32_t *)QDMA_CNT = (u32_t) Count;
*(u32_t *)QDMA_IDX = 0x00000000;
*(u32_t *)QDMA_S_OPT = 0x28200001;
buf += Count*2;
#else
for (loop=0;loop < Count ;loop++){
*(u16_t *)buf = EN_DATA ;
buf += 2;
}
#endif //QDMA_Enabled
while ((EN0_ISR & ENISR_RDC) == 0);
EN0_ISR = (u8_t) ENISR_RDC;
if (flagOdd) {
EN0_RCNTLO = 0x01;
EN0_RCNTHI = 0x00;
EN0_RSARLO = (u8_t) (remote_Addr & 0xff);
EN0_RSARHI = (u8_t) (remote_Addr >> 8);
EN_CMD = (u8_t) (EN_PAGE0 + EN_RREAD + EN_START);
remote_Addr += 1;
*(u8_t *)buf = *(u8_t *)(Base_ADDR+0x10) ;
while ((EN0_ISR & ENISR_RDC) == 0);
EN0_ISR = (u8_t) ENISR_RDC;
}
return remote_Addr;
}
/*----------------------------------------------------------------------------------------
****************************************************************************************
----------------------------------------------------------------------------------------*/
/**
* ne2k_rx_err.
*/
void ne2k_rx_err(void)
{
u8_t curr;
@ -494,37 +552,37 @@ void ne2k_rx_err(void)
EN0_BOUNDARY = (u8_t) curr-1;
}
/*-----------------------------------------------------------------------------------*/
/**
* ne2k_rx.
*/
void ne2k_rx(void)
{
u8_t curr,bnry;
u8_t curr,bnry,loopCnt = 0;
while(loopCnt < 10) {
EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
curr = (u8_t) EN1_CURR;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
bnry = (u8_t) EN0_BOUNDARY + 1;//millin + 1
bnry = (u8_t) EN0_BOUNDARY + 1;
if (bnry >= RX_STOP_PG)
bnry = RX_START_PG;
while(curr != bnry){
ne2k_input(ne2k_if_netif);
EN_CMD = (u8_t) (EN_PAGE1 + EN_NODMA + EN_STOP);
curr = (u8_t) EN1_CURR;
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_STOP);
bnry = (u8_t) EN0_BOUNDARY + 1; //millin +1
}
if (curr == bnry) break;
ne2k_input(ne2k_if_netif);
loopCnt++;
}
}
/* -----------------------------
/*---*---*---*---*---*---*---*
* void ne2k_isr(void)
* can be int 4 5 6 or 7
* ----------------------------*/
void
ne2k_isr(void)
*---*---*---*---*---*---*---*/
void ne2k_isr(void)
{
DSP_C6x_Save();
OSIntEnter();
@ -576,11 +634,10 @@ ne2k_isr(void)
EN0_ISR = (u8_t) 0xff; // clear ISR
EN0_IMR = (u8_t) (ENISR_OVER + ENISR_RX + ENISR_RX_ERR);
//(ENISR_OVER + ENISR_RX + ENISR_TX + ENISR_TX_ERR);
//open nic for next packet
EN_CMD = (u8_t) (EN_PAGE0 + EN_NODMA + EN_START);
if (led_stat & 0x04) {LED3_on;}
else {LED3_off;}

View File

@ -46,7 +46,7 @@
#include "..\lwIP\src\api\err.c"
#include "..\lwIP\src\api\sockets.c"
// sample task code (tcp-echo|telnet & http demo)
// sample task code (http demo)
#include "sample_http.c"
struct netif ne2kif_if;
@ -90,7 +90,7 @@ void Task_lwip_init(void * pParam)
//add ne2k interface
IP4_ADDR(&gw, 166,111,32,1);
IP4_ADDR(&ipaddr, 166,111,33,120);
IP4_ADDR(&netmask, 255,255,252,0);
IP4_ADDR(&netmask, 255,255,254,0);
netif_add(&ne2kif_if, &ipaddr, &netmask, &gw, NULL, ne2k_init, tcpip_input);
netif_set_default(&ne2kif_if);
@ -99,12 +99,10 @@ void Task_lwip_init(void * pParam)
printf("Applications started.\n");
//------------------------------------------------------------
//All thread(task) of lwIP must have their PRI between 5 and 9.
// http thread, a web page can be browsed
sys_thread_new(httpd_init, (void*)"httpd",6);
//All thread(task) of lwIP must have their PRI between 10 and 14.
// sys_thread_new(httpd_init, (void*)"httpd",10);
//------------------------------------------------------------
httpd_init();//sample_http
printf("lwIP threads created!\n");

View File

@ -30,7 +30,7 @@
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: lwipopts.h,v 1.1 2005/01/29 15:19:21 ming Exp $
* $Id: lwipopts.h,v 1.2 2005/11/07 00:50:50 ming Exp $
*/
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
@ -58,69 +58,76 @@
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
byte alignment -> define MEM_ALIGNMENT to 2. */
#define MEM_ALIGNMENT 4
/* MEM_SIZE: the size of the heap memory. If the application will send
a lot of data that needs to be copied, this should be set high. */
#define MEM_SIZE 512000//1600
#define MEM_SIZE 65536
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
sends a lot of data out of ROM (or other static memory), this
should be set high. */
#define MEMP_NUM_PBUF 64//16
#define MEMP_NUM_PBUF 32
/* Number of raw connection PCBs */
#define MEMP_NUM_RAW_PCB 4
#define MEMP_NUM_RAW_PCB 8
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#define MEMP_NUM_UDP_PCB 6//4
#define MEMP_NUM_UDP_PCB 8
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
connections. */
#define MEMP_NUM_TCP_PCB 10//5
#define MEMP_NUM_TCP_PCB 8
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
connections. */
#define MEMP_NUM_TCP_PCB_LISTEN 8//6///8
#define MEMP_NUM_TCP_PCB_LISTEN 2
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#define MEMP_NUM_TCP_SEG 16//8//16
#define MEMP_NUM_TCP_SEG 32
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
#define MEMP_NUM_SYS_TIMEOUT 3
#define MEMP_NUM_SYS_TIMEOUT 8
//----------------------------------------------------------------------
/* The following four are used only with the sequential API and can be
set to 0 if the application only will use the raw API. */
//----------------------------------------------------------------------
/* MEMP_NUM_NETBUF: the number of struct netbufs. */
#define MEMP_NUM_NETBUF 64//2
#define MEMP_NUM_NETBUF 32
/* MEMP_NUM_NETCONN: the number of struct netconns. */
#define MEMP_NUM_NETCONN 64//4
#define MEMP_NUM_NETCONN 32
/* MEMP_NUM_APIMSG: the number of struct api_msg, used for
communication between the TCP/IP stack and the sequential
programs. */
#define MEMP_NUM_API_MSG 64//8
#define MEMP_NUM_API_MSG 32
/* MEMP_NUM_TCPIPMSG: the number of struct tcpip_msg, which is used
for sequential API communication and incoming packets. Used in
src/api/tcpip.c. */
#define MEMP_NUM_TCPIP_MSG 64//16//8
#define MEMP_NUM_TCPIP_MSG 32
//----------------------------------------------------------------------
/* ---------- Pbuf options ---------- */
//----------------------------------------------------------------------
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#define PBUF_POOL_SIZE 128//16 must>6
#define PBUF_POOL_SIZE 16
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
#define PBUF_POOL_BUFSIZE 2048//128
/* PBUF_LINK_HLEN: the number of bytes that should be allocated for a
link level header. */
#define PBUF_LINK_HLEN 14//16//14
#define PBUF_POOL_BUFSIZE 1536
//----------------------------------------------------------------------
/* ---------- ARP options ---------- */
//----------------------------------------------------------------------
/** Number of active hardware address, IP address pairs cached */
#define ARP_TABLE_SIZE 20//10
#define ARP_TABLE_SIZE 10//10
/**
* If enabled, outgoing packets are queued during hardware address
* resolution.
@ -140,35 +147,25 @@ a lot of data that needs to be copied, this should be set high. */
//----------------------------------------------------------------------
/* ---------- IP options ---------- */
//----------------------------------------------------------------------
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
IP packets across network interfaces. If you are going to run lwIP
on a device with only one network interface, define this to 0. */
#define IP_FORWARD 0
/* If defined to 1, IP options are allowed (but not parsed). If
defined to 0, all packets with IP options are dropped. */
#define IP_OPTIONS 0
/** IP reassembly and segmentation. Even if they both deal with IP
* fragments, note that these are orthogonal, one dealing with incoming
* packets, the other with outgoing packets
*/
/** Reassemble incoming fragmented IP packets */
#define IP_REASSEMBLY 1
#define IP_REASSEMBLY 0
/** Fragment outgoing IP packets if their size exceeds MTU */
#define IP_FRAG 1
//----------------------------------------------------------------------
/* ---------- ICMP options ---------- */
//----------------------------------------------------------------------
#define ICMP_TTL 255
//----------------------------------------------------------------------
/* ---------- RAW options ---------- */
//----------------------------------------------------------------------
#define LWIP_RAW 1
#define RAW_TTL 255
#define IP_FRAG 0
//----------------------------------------------------------------------
@ -179,6 +176,7 @@ a lot of data that needs to be copied, this should be set high. */
interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
turning this on does currently not work. */
#define LWIP_DHCP 0
/* 1 if you want to do an ARP check on the offered address
(recommended). */
#define DHCP_DOES_ARP_CHECK 1
@ -188,34 +186,31 @@ a lot of data that needs to be copied, this should be set high. */
/* ---------- UDP options ---------- */
//----------------------------------------------------------------------
#define LWIP_UDP 1
#define UDP_TTL 255
//----------------------------------------------------------------------
/* ---------- TCP options ---------- */
//----------------------------------------------------------------------
#define LWIP_TCP 1
#define TCP_TTL 255
/* TCP receive window. */
#define TCP_WND 8192//1024//2048
#define TCP_WND 32768
/* Maximum number of retransmissions of data segments. */
#define TCP_MAXRTX 12
#define TCP_MAXRTX 4
/* Maximum number of retransmissions of SYN segments. */
#define TCP_SYNMAXRTX 4//6
#define TCP_SYNMAXRTX 4
/* Controls if TCP should queue segments that arrive out of
order. Define to 0 if your device is low on memory. */
#define TCP_QUEUE_OOSEQ 1
/* TCP Maximum segment size. */
#define TCP_MSS 1024//128
#define TCP_MSS 1476
/* TCP sender buffer space (bytes). */
#define TCP_SND_BUF 8192//256
/* TCP sender buffer space (pbufs). This must be at least = 2 *
TCP_SND_BUF/TCP_MSS for things to work. */
#define TCP_SND_QUEUELEN 4 * TCP_SND_BUF/TCP_MSS
/* TCP writable space (bytes). This must be less than or equal
to TCP_SND_BUF. It is the amount of space which must be
available in the tcp snd_buf for select to return writable */
#define TCP_SNDLOWAT TCP_SND_BUF/2
#define TCP_SND_BUF 32768
//----------------------------------------------------------------------
@ -223,10 +218,7 @@ a lot of data that needs to be copied, this should be set high. */
//----------------------------------------------------------------------
/* Support loop interface (127.0.0.1) */
#define LWIP_HAVE_LOOPIF 0
//#define LWIP_EVENT_API 1//
#define LWIP_CALLBACK_API 1// only one of these two
#define LWIP_HAVE_LOOPIF 0
#define LWIP_COMPAT_SOCKETS 1
@ -234,7 +226,6 @@ a lot of data that needs to be copied, this should be set high. */
#define TCPIP_THREAD_PRIO 5 //millin
//#define SLIPIF_THREAD_PRIO 1
//#define PPP_THREAD_PRIO 1
//#define DEFAULT_THREAD_PRIO 1
//----------------------------------------------------------------------

View File

@ -23,10 +23,10 @@ const void * const pvNullPointer;
static char pcQueueMemoryPool[MAX_QUEUES * sizeof(TQ_DESCR) ];
struct sys_timeouts lwip_timeouts[LWIP_TASK_MAX];
struct sys_timeouts lwip_timeouts[LWIP_TASK_MAX+1];
struct sys_timeouts null_timeouts;
OS_STK LWIP_TASK_STK[LWIP_TASK_MAX][LWIP_STK_SIZE];
OS_STK LWIP_TASK_STK[LWIP_TASK_MAX+1][LWIP_STK_SIZE];
/*-----------------------------------------------------------------------------------*/
@ -39,7 +39,7 @@ void sys_init(void)
//init mem used by sys_mbox_t //use ucosII functions
pQueueMem = OSMemCreate( (void*)pcQueueMemoryPool, MAX_QUEUES, sizeof(TQ_DESCR), &ucErr );
//init lwip_timeouts for every lwip task
for(i=0;i<LWIP_TASK_MAX;i++){
for(i=0;i<LWIP_TASK_MAX+1;i++){
lwip_timeouts[i].next = NULL;
}
}
@ -186,14 +186,14 @@ sys_timeouts * sys_arch_timeouts(void)
curr_prio = curr_task_pcb.OSTCBPrio;
offset = curr_prio - LWIP_START_PRIO;
//not called by a lwip task ,return timeouts->NULL
if(offset < 0 || offset >= LWIP_TASK_MAX)
{
return &null_timeouts;
}
return &lwip_timeouts[offset];
if(curr_prio == TCPIP_THREAD_PRIO)
return &lwip_timeouts[LWIP_TASK_MAX];
else if(offset >= 0 && offset < LWIP_TASK_MAX)
return &lwip_timeouts[offset];
else return &null_timeouts;
//if not called by a lwip task ,return timeouts->NULL
}
@ -201,10 +201,15 @@ sys_timeouts * sys_arch_timeouts(void)
sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio)
{
if(prio - LWIP_START_PRIO < LWIP_TASK_MAX){
if(prio == TCPIP_THREAD_PRIO){
OSTaskCreate(thread, (void *)0x1111, &LWIP_TASK_STK[LWIP_TASK_MAX][LWIP_STK_SIZE-1], prio);
return prio;
}
else if(prio - LWIP_START_PRIO < LWIP_TASK_MAX){
OSTaskCreate(thread, (void *)0x1111, &LWIP_TASK_STK[prio - LWIP_START_PRIO][LWIP_STK_SIZE-1], prio);
return prio;
} else {
}
else {
printf(" lwip task prio out of range ! error! ");
return 0;
}