aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2008-05-21 13:57:47 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2008-05-21 13:57:47 +0000
commitb34347c0257b14e5da0704ba2c710f39a9f9f002 (patch)
tree2e072c0c7c4c0a102e4ebe3186357a79cd8dff64
parentf2022a264125bdf3b18e5fe0fe0c2e523cf41ded (diff)
downloadChibiOS-b34347c0257b14e5da0704ba2c710f39a9f9f002.tar.gz
ChibiOS-b34347c0257b14e5da0704ba2c710f39a9f9f002.tar.bz2
ChibiOS-b34347c0257b14e5da0704ba2c710f39a9f9f002.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@303 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r--demos/ARM7-AT91SAM7X-WEB-GCC/Makefile2
-rw-r--r--demos/ARM7-AT91SAM7X-WEB-GCC/Makefile.thumb2
-rw-r--r--demos/ARM7-AT91SAM7X-WEB-GCC/web/webthread.c118
-rw-r--r--ports/ARM7-AT91SAM7X/sam7x_emac.c49
-rw-r--r--ports/ARM7-AT91SAM7X/sam7x_emac.h11
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 <http://www.gnu.org/licenses/>.
*/
+#include <string.h>
+
#include <ch.h>
#include <evtimer.h>
#include <sam7x_emac.h>
@@ -27,8 +29,59 @@
#include <timer.h>
#include <clock-arch.h>
+#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 <http://www.gnu.org/licenses/>.
*/
-#include <ch.h>
-
#include <string.h>
+#include <ch.h>
+
#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]);
@@ -286,10 +286,50 @@ bool_t EMACGetLinkStatus(void) {
}
/*
+ * 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
}