aboutsummaryrefslogtreecommitdiff
path: root/libraries/ethernet
diff options
context:
space:
mode:
authorPerry Hung <iperry@alum.mit.edu>2010-06-04 18:01:16 -0400
committerPerry Hung <iperry@alum.mit.edu>2010-06-11 15:12:01 -0400
commit32d4a18a16afc5d3416ff602b008308ab373a89e (patch)
tree55cd4aab7388bfc270c50819b35bd9408a5f51d9 /libraries/ethernet
parent59728136a7374b358fb599d69b09497a21119133 (diff)
basic socket interfaceethernet-shield
Diffstat (limited to 'libraries/ethernet')
-rw-r--r--libraries/ethernet/socket.c127
-rw-r--r--libraries/ethernet/socket.h27
-rw-r--r--libraries/ethernet/w5100.cpp51
-rw-r--r--libraries/ethernet/w5100.h (renamed from libraries/ethernet/ethernet.h)26
4 files changed, 228 insertions, 3 deletions
diff --git a/libraries/ethernet/socket.c b/libraries/ethernet/socket.c
new file mode 100644
index 0000000..8ccfdd3
--- /dev/null
+++ b/libraries/ethernet/socket.c
@@ -0,0 +1,127 @@
+#include "wirish.h"
+#include "w5100.h"
+#include "socket.h"
+
+#define ETHERNET_DEBUG
+
+#ifdef ETHERNET_DEBUG
+ #define ETH_DBG(...) iprintf(__VA_ARGS__)
+#else
+ #define ETH_DBG(...)
+#endif
+
+
+int32 socket(int32 type) {
+ /* tcp */
+ w5100_write(SOCKET0_BASE + SN_MR, 0x01);
+}
+
+int32 bind(int32 sockfd, uint16 port) {
+ int32 rc;
+ /* port 80 */
+ w5100_write(SOCKET0_BASE + SN_PORT0, 0x00);
+ w5100_write(SOCKET0_BASE + SN_PORT1, 80); // low byte
+
+ /* open */
+ ETH_DBG("open()\n");
+ w5100_write(SOCKET0_BASE + SN_CR, CR_OPEN);
+ rc = w5100_read(SOCKET0_BASE + SN_SR);
+ ETH_DBG("SR: 0x%0x\n", rc);
+
+}
+
+static char buf[2048];
+
+int32 listen(int32 sockfd) {
+ uint16 bytesAvailable = 0;
+ uint32 i;
+ int32 rc;
+
+ /* listen */
+ ETH_DBG("listen()\n");
+ w5100_write(SOCKET0_BASE + SN_CR, CR_LISTEN);
+ rc = w5100_read(SOCK_ADDR(0, SN_SR));
+ ETH_DBG("SR: 0x%0x\n", rc);
+
+ /* wait for connection */
+ while(1) {
+ if (w5100_read(SOCK_ADDR(0, SN_SR)) == SOCK_ESTABLISHED) {
+ ETH_DBG("Connection received\n");
+ break;
+ }
+ }
+ /* wait for data */
+ while (!bytesAvailable) {
+ bytesAvailable += (w5100_read(SOCK_ADDR(0, SN_RX_RSR0)) << 8);
+ bytesAvailable += w5100_read(SOCK_ADDR(0, SN_RX_RSR1));
+ }
+ ETH_DBG("recv: %u bytes\n", bytesAvailable);
+
+ /* Read them out */
+ uint32 rxrd = w5100_read(SOCK_ADDR(0, SN_RX_RD0)) << 8;
+ rxrd += w5100_read(SOCK_ADDR(0, SN_RX_RD1));
+ ETH_DBG("rxrd: %u\n", rxrd);
+
+ for (i = 0; i < bytesAvailable; i++) {
+ buf[i] = w5100_read(0x6000 + i);
+ iprintf("%c", buf[i]);
+ }
+
+ sprintf(buf, "HTTP/1.1 200 OK\r\n"
+ "Content-Type: text/html\r\n\r\n"
+ "analogInput(2): %u<BR>"
+ "analogInput(15): %u<BR>"
+ "analogInput(16): %u<BR>"
+ "analogInput(17): %u<BR>"
+ "analogInput(18): %u<BR>"
+ "analogInput(19): %u<BR>"
+ "analogInput(20): %u<BR>"
+ "analogInput(27): %u<BR>"
+ "analogInput(28): %u<BR>"
+ "watch out for cows",
+ analogRead(2),
+ analogRead(15),
+ analogRead(16),
+ analogRead(17),
+ analogRead(18),
+ analogRead(19),
+ analogRead(20),
+ analogRead(27),
+ analogRead(28));
+
+ uint32 send_size = strlen(buf);
+
+ iprintf("sending %u bytes()\n", send_size);
+
+ uint16 txwr;
+ uint16 get_offset;
+ uint16 get_start_address;
+ uint16 tx_mask = 0x07ff;
+ /* calculate offset address */
+ txwr = w5100_read(SOCK_ADDR(0, SN_TX_WR0)) << 8;
+ txwr += w5100_read(SOCK_ADDR(0, SN_TX_WR1));
+ iprintf("SN_TX_WR: %x\n", txwr);
+
+ get_offset = txwr & tx_mask;
+ get_start_address = 0x4000 + get_offset;
+
+ iprintf("get_offset: %x send_size: %u\n" , get_offset, send_size);
+
+ /* copy data to get_start_address */
+ for (i = 0; i < send_size; i++) {
+ w5100_write(get_start_address + i, buf[i]);
+ }
+
+ txwr += send_size;
+
+ w5100_write(SOCK_ADDR(0, SN_TX_WR0), (txwr & 0xFF00) >> 8 );
+ w5100_write(SOCK_ADDR(0, SN_TX_WR1), (txwr & 0x00FF));
+ w5100_write(SOCK_ADDR(0, SN_CR), CR_SEND);
+
+ delay(1);
+ w5100_write(SOCK_ADDR(0, SN_CR), CR_DISCON);
+ delay(1);
+ w5100_write(SOCK_ADDR(0, SN_CR), CR_CLOSE);
+}
+
+
diff --git a/libraries/ethernet/socket.h b/libraries/ethernet/socket.h
new file mode 100644
index 0000000..c6efa90
--- /dev/null
+++ b/libraries/ethernet/socket.h
@@ -0,0 +1,27 @@
+#ifndef _SOCKET_H_
+#define _SOCKET_H_
+
+/**
+ * @brief socket operations
+ */
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+
+enum sock_type {
+ SOCK_STREAM = 0x1,
+ SOCK_DGRAM = 0x2
+};
+
+int32 socket(int32 type);
+int32 bind(int32 sockfd, uint16 port);
+int32 listen(int32 sockfd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/libraries/ethernet/w5100.cpp b/libraries/ethernet/w5100.cpp
new file mode 100644
index 0000000..8c6551d
--- /dev/null
+++ b/libraries/ethernet/w5100.cpp
@@ -0,0 +1,51 @@
+#include "wirish.h"
+#include "w5100.h"
+
+
+extern HardwareSPI spi;
+
+void w5100_init(k) {
+
+}
+
+void w5100_reset(void) {
+ w5100_write(MR, MR_RST);
+}
+
+void w5100_write_buf(uint16 addr, uint8 *buf, uint8 len) {
+ uint32 i;
+ for (i = 0; i < len; i++) {
+ w5100_write(addr + i, buf[i]);
+ }
+}
+
+void w5100_read_buf(uint16 addr, uint8 *buf, uint8 len) {
+ uint32 i;
+ for (i = 0; i < len; i++) {
+ buf[i] = w5100_read(addr + i);
+ }
+}
+
+uint8 w5100_send_cmd(uint8 opcode, uint16 addr, uint8 data) {
+ uint8 buf[4];
+ uint8 rc = 0;
+
+ buf[0] = opcode;
+ buf[1] = (addr >> 8);
+ buf[2] = (addr & 0xFF);
+ buf[3] = data;
+
+ digitalWrite(SS, LOW);
+ rc = spi.send(buf, 4);
+ digitalWrite(SS, HIGH);
+
+#ifdef SPI_DEBUG
+ if (opcode == OPCODE_WRITE) {
+ iprintf("\tWrite: 0x%04x = 0x%x\n", addr, data);
+ } else {
+ iprintf("\tRead: 0x%04x = 0x%x\n", addr, rc);
+ }
+#endif
+
+ return rc;
+}
diff --git a/libraries/ethernet/ethernet.h b/libraries/ethernet/w5100.h
index c533b04..7f8c8b0 100644
--- a/libraries/ethernet/ethernet.h
+++ b/libraries/ethernet/w5100.h
@@ -1,9 +1,16 @@
/**
- * @brief
+ * @brief wiznet 5100
*/
-#ifndef _ETHERNET_H_
-#define _ETHERNET_H_
+#ifndef _W5100_H_
+#define _W5100_H_
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+/* slave select on maple pin 10 */
+#define SS 10
#define MR 0x0000
#define MR_RST 0x80
@@ -157,5 +164,18 @@
) : 0x00 \
)
+#define w5100_write(addr, data) w5100_send_cmd(OPCODE_WRITE, addr, data)
+#define w5100_read(addr) w5100_send_cmd(OPCODE_READ, addr, 0xFF)
+
+uint8 w5100_send_cmd(uint8 opcode, uint16 addr, uint8 data);
+void w5100_reset(void);
+void w5100_write_buf(uint16 addr, uint8 *buf, uint8 len);
+void w5100_read_buf(uint16 addr, uint8 *buf, uint8 len);
+
+
+#ifdef __cplusplus
+}
+#endif
+
#endif