From b34347c0257b14e5da0704ba2c710f39a9f9f002 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 21 May 2008 13:57:47 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@303 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARM7-AT91SAM7X-WEB-GCC/Makefile | 2 +- demos/ARM7-AT91SAM7X-WEB-GCC/Makefile.thumb | 2 +- demos/ARM7-AT91SAM7X-WEB-GCC/web/webthread.c | 118 +++++++++++++++++++++++++-- ports/ARM7-AT91SAM7X/sam7x_emac.c | 49 ++++++++++- ports/ARM7-AT91SAM7X/sam7x_emac.h | 11 +-- 5 files changed, 161 insertions(+), 21 deletions(-) diff --git a/demos/ARM7-AT91SAM7X-WEB-GCC/Makefile b/demos/ARM7-AT91SAM7X-WEB-GCC/Makefile index 0e66ef5ee..0f9806151 100644 --- a/demos/ARM7-AT91SAM7X-WEB-GCC/Makefile +++ b/demos/ARM7-AT91SAM7X-WEB-GCC/Makefile @@ -121,7 +121,7 @@ TOPT = -mthumb -D THUMB # chconf.h. # NOTE: -falign-functions=16 may improve the performance, not always, but # increases the code size. -OPT = -ggdb -fomit-frame-pointer -mabi=apcs-gnu +OPT = -O2 -ggdb -fomit-frame-pointer -mabi=apcs-gnu #OPT += -ffixed-r7 #OPT += -falign-functions=16 diff --git a/demos/ARM7-AT91SAM7X-WEB-GCC/Makefile.thumb b/demos/ARM7-AT91SAM7X-WEB-GCC/Makefile.thumb index 9171d3084..1ff7b8211 100644 --- a/demos/ARM7-AT91SAM7X-WEB-GCC/Makefile.thumb +++ b/demos/ARM7-AT91SAM7X-WEB-GCC/Makefile.thumb @@ -121,7 +121,7 @@ TOPT = -mthumb -D THUMB # chconf.h. # NOTE: -falign-functions=16 may improve the performance, not always, but # increases the code size. -OPT = -ggdb -fomit-frame-pointer -mabi=apcs-gnu +OPT = -O2 -ggdb -fomit-frame-pointer -mabi=apcs-gnu #OPT += -ffixed-r7 #OPT += -falign-functions=16 diff --git a/demos/ARM7-AT91SAM7X-WEB-GCC/web/webthread.c b/demos/ARM7-AT91SAM7X-WEB-GCC/web/webthread.c index a4fb3de03..c99813fe8 100644 --- a/demos/ARM7-AT91SAM7X-WEB-GCC/web/webthread.c +++ b/demos/ARM7-AT91SAM7X-WEB-GCC/web/webthread.c @@ -17,6 +17,8 @@ along with this program. If not, see . */ +#include + #include #include #include @@ -27,8 +29,59 @@ #include #include +#define IPADDR0 10 +#define IPADDR1 151 +#define IPADDR2 218 +#define IPADDR3 245 + +#define SEND_RETRY_MAX 10 +#define SEND_RETRY_INTERVAL 2 + +static const struct uip_eth_addr macaddr = { + {0xC2, 0xAF, 0x51, 0x03, 0xCF, 0x46} +}; + static EvTimer evt; -struct EventListener el0, el1, el2; +struct EventListener el0, el1; + +#define BUF ((struct uip_eth_hdr *)&uip_buf[0]) + +/* + * uIP send function wrapping the EMAC functions. + */ +static void network_device_send(void) { + int i; + BufDescriptorEntry *bdep; + + for (i = 0; i < SEND_RETRY_MAX; i++) { + if ((bdep = EMACGetTransmitbuffer()) != NULL) { + uint8_t *bp = (uint8_t *)bdep->w1; + + if(uip_len <= UIP_LLH_LEN + UIP_TCPIP_HLEN) + memcpy(bp, &uip_buf[0], uip_len); + else { + memcpy(bp, &uip_buf[0], UIP_LLH_LEN + UIP_TCPIP_HLEN); + memcpy(bp + UIP_LLH_LEN + UIP_TCPIP_HLEN, + uip_appdata, + uip_len - (UIP_LLH_LEN + UIP_TCPIP_HLEN)); + } + EMACTransmit(bdep, uip_len); + return; + } + chThdSleep(SEND_RETRY_INTERVAL); + } + /* Dropped... */ +} + +/* + * uIP receive function wrapping the EMAC function. + */ +static size_t network_device_read(void) { + size_t size = UIP_CONF_BUFFER_SIZE; + if (EMACReceive(uip_buf, &size)) + return size; + return 0; +} void clock_init(void) {} @@ -38,7 +91,7 @@ clock_time_t clock_time( void ) } /* - * Executed as event handler at 1000mS intervals. + * Ethernet link status monitor. */ static void TimerHandler(eventid_t id) { @@ -48,18 +101,69 @@ static void TimerHandler(eventid_t id) { msg_t WebThread(void *p) { static const evhandler_t evhndl[] = { TimerHandler, - NULL, NULL }; + uip_ipaddr_t ipaddr; + struct timer periodic_timer, arp_timer; + + EMACSetAddress(&macaddr.addr[0]); + /* + * Event sources setup. + */ evtInit(&evt, 1000); /* Initializes an event timer object. */ evtStart(&evt); /* Starts the event timer. */ chEvtRegister(&evt.et_es, &el0, 0); /* Registers on the timer event source. */ - chEvtRegister(&EMACFrameTransmitted, &el1, 1); - chEvtRegister(&EMACFrameReceived, &el2, 2); - + chEvtRegister(&EMACFrameReceived, &el1, 1); + + /* + * uIP initialization. + */ + timer_set(&periodic_timer, 500); + timer_set(&arp_timer, 10000); + uip_init(); + uip_setethaddr(macaddr); + uip_ipaddr(ipaddr, IPADDR0, IPADDR1, IPADDR2, IPADDR3); + uip_sethostaddr(ipaddr); + httpd_init(); + while (TRUE) { - chEvtWait(ALL_EVENTS, evhndl); + uip_len = network_device_read(); + if (uip_len > 0) { + if (BUF->type == htons(UIP_ETHTYPE_IP)) { + uip_arp_ipin(); + uip_input(); + if (uip_len > 0) { + uip_arp_out(); + network_device_send(); + } + } + else if (BUF->type == htons(UIP_ETHTYPE_ARP)) { + uip_arp_arpin(); + if (uip_len > 0) + network_device_send(); + } + } + else { + if (timer_expired(&periodic_timer)) { + int i; + timer_reset(&periodic_timer); + for (i = 0; i < UIP_CONNS; i++) { + uip_periodic(i); + if (uip_len > 0) { + uip_arp_out(); + network_device_send(); + } + } + if (timer_expired(&arp_timer)) { + timer_reset(&arp_timer); + uip_arp_timer(); + } + } + else { + chEvtWait(ALL_EVENTS, evhndl); + } + } } return 0; } diff --git a/ports/ARM7-AT91SAM7X/sam7x_emac.c b/ports/ARM7-AT91SAM7X/sam7x_emac.c index 0a3d1144b..e55c6fcd6 100644 --- a/ports/ARM7-AT91SAM7X/sam7x_emac.c +++ b/ports/ARM7-AT91SAM7X/sam7x_emac.c @@ -17,10 +17,10 @@ along with this program. If not, see . */ -#include - #include +#include + #include "board.h" #include "sam7x_emac.h" #include "mii.h" @@ -242,7 +242,7 @@ void InitEMAC(int prio) { /* * Set the MAC address. */ -void EMACSetAddress(uint8_t *eaddr) { +void EMACSetAddress(const uint8_t *eaddr) { AT91C_BASE_EMAC->EMAC_SA1L = (AT91_REG)((eaddr[3] << 24) | (eaddr[2] << 16) | (eaddr[1] << 8) | eaddr[0]); @@ -285,11 +285,51 @@ bool_t EMACGetLinkStatus(void) { return link_up = TRUE; } +/* + * Allocates and locks a buffer for a transmission operation. + */ +BufDescriptorEntry *EMACGetTransmitbuffer(void) { + BufDescriptorEntry *cptr; + + if (!link_up) + return NULL; + + chSysLock(); + cptr = txptr; + if (!(cptr->w2 & W2_T_USED) || + (cptr->w2 & W2_T_LOCKED)) { + chSysUnlock(); + return FALSE; + } + cptr->w2 |= W2_T_LOCKED; /* Locks the buffer while copying.*/ + if (++txptr >= &tent[EMAC_TRANSMIT_BUFFERS]) + txptr = tent; + chSysUnlock(); + return cptr; +} + +/* + * Transmits a previously allocated buffer and then releases it. + */ +void EMACTransmit(BufDescriptorEntry *cptr, size_t size) { + + chDbgAssert(size < EMAC_TRANSMIT_BUFFERS_SIZE, "sam7x_emac.c, EMACTransmit"); + + cptr->w2 &= ~W2_R_LENGTH_MASK; + cptr->w2 |= size; + + chSysLock(); + cptr->w2 &= ~(W2_T_USED | W2_T_LOCKED); + AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART; + chSysUnlock(); +} + /* * Transmits an ethernet frame. * Returns TRUE if the frame is queued for transmission else FALSE. */ -bool_t EMACTransmit(struct MACHeader *hdr, uint8_t *data, size_t size) { +#if 0 +bool_t EMACTransmit2(struct MACHeader *hdr, uint8_t *data, size_t size) { uint8_t *p; BufDescriptorEntry *cptr; @@ -332,6 +372,7 @@ bool_t EMACTransmit(struct MACHeader *hdr, uint8_t *data, size_t size) { chSysUnlock(); return TRUE; } +#endif /* * Reads a buffered frame. diff --git a/ports/ARM7-AT91SAM7X/sam7x_emac.h b/ports/ARM7-AT91SAM7X/sam7x_emac.h index aa69a5e29..d585f1fe2 100644 --- a/ports/ARM7-AT91SAM7X/sam7x_emac.h +++ b/ports/ARM7-AT91SAM7X/sam7x_emac.h @@ -61,19 +61,14 @@ typedef struct { #define W2_T_WRAP 0x40000000 #define W2_T_USED 0x80000000 -struct MACHeader { - uint8_t destination[6]; - uint8_t source[6]; - uint8_t ethertype[2]; -}; - #ifdef __cplusplus extern "C" { #endif void InitEMAC(int prio); - void EMACSetAddress(uint8_t *eaddr); + void EMACSetAddress(const uint8_t *eaddr); bool_t EMACGetLinkStatus(void); - bool_t EMACTransmit(struct MACHeader *hdr, uint8_t *data, size_t size); + BufDescriptorEntry *EMACGetTransmitbuffer(void); + void EMACTransmit(BufDescriptorEntry *cptr, size_t size); bool_t EMACReceive(uint8_t *buf, size_t *sizep); #ifdef __cplusplus } -- cgit v1.2.3