From 32d4a18a16afc5d3416ff602b008308ab373a89e Mon Sep 17 00:00:00 2001 From: Perry Hung Date: Fri, 4 Jun 2010 18:01:16 -0400 Subject: basic socket interface --- Makefile | 7 +- libraries/ethernet/ethernet.h | 161 ------------------------------------- libraries/ethernet/socket.c | 127 +++++++++++++++++++++++++++++ libraries/ethernet/socket.h | 27 +++++++ libraries/ethernet/w5100.cpp | 51 ++++++++++++ libraries/ethernet/w5100.h | 181 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 391 insertions(+), 163 deletions(-) delete mode 100644 libraries/ethernet/ethernet.h create mode 100644 libraries/ethernet/socket.c create mode 100644 libraries/ethernet/socket.h create mode 100644 libraries/ethernet/w5100.cpp create mode 100644 libraries/ethernet/w5100.h diff --git a/Makefile b/Makefile index f497900..256e142 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,8 @@ OUTDIRS = $(BUILD_PATH)/$(LIB_PATH) \ $(BUILD_PATH)/wirish \ $(BUILD_PATH)/wirish/comm \ $(BUILD_PATH)/$(LIB_PATH)/usb \ - $(BUILD_PATH)/$(LIB_PATH)/usb/usb_lib + $(BUILD_PATH)/$(LIB_PATH)/usb/usb_lib \ + $(BUILD_PATH)/libraries/ethernet @@ -87,7 +88,8 @@ CSRC = libmaple/systick.c \ libmaple/usb/usb_lib/usb_init.c \ libmaple/usb/usb_lib/usb_int.c \ libmaple/usb/usb_lib/usb_mem.c \ - libmaple/usb/usb_lib/usb_regs.c \ + libraries/ethernet/socket.c \ + libmaple/usb/usb_lib/usb_regs.c CPPSRC = wirish/wirish_math.cpp \ wirish/Print.cpp \ @@ -95,6 +97,7 @@ CPPSRC = wirish/wirish_math.cpp \ wirish/comm/HardwareSPI.cpp \ wirish/usb_serial.cpp \ wirish/cxxabi-compat.cpp \ + libraries/ethernet/w5100.cpp \ main.cpp # i really have no idea what i'm doing diff --git a/libraries/ethernet/ethernet.h b/libraries/ethernet/ethernet.h deleted file mode 100644 index c533b04..0000000 --- a/libraries/ethernet/ethernet.h +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @brief - */ - -#ifndef _ETHERNET_H_ -#define _ETHERNET_H_ - -#define MR 0x0000 -#define MR_RST 0x80 - -/* Gateway IP Address Register */ -#define GAR0 0x0001 -#define GAR1 0x0002 -#define GAR2 0x0003 -#define GAR3 0x0004 -#define GAR GAR0 - -/* Subnet mask register */ -#define SUBR0 0x0005 -#define SUBR1 0x0006 -#define SUBR2 0x0007 -#define SUBR3 0x0008 -#define SUBR SUBR0 - -/* Source Hardware Address Register */ -#define SHAR0 0x0009 -#define SHAR1 0x000A -#define SHAR2 0x000B -#define SHAR3 0x000C -#define SHAR4 0x000D -#define SHAR5 0x000E -#define SHAR SHAR0 - -/* Source IP Address register */ -#define SIPR0 0x000F -#define SIPR1 0x0010 -#define SIPR2 0x0011 -#define SIPR3 0x0012 -#define SIPR SIPR0 - -/* Interrupt register */ -#define IR 0x0015 -#define IR_CONFLICT BIT(7) -#define IR_UNREACH BIT(6) -#define IR_PPOE BIT(5) -#define IR_S3_INT BIT(3) -#define IR_S2_INT BIT(2) -#define IR_S1_INT BIT(1) -#define IR_S0_INT BIT(0) - -/* Interrupt mask register */ -#define IMR 0x0016 -#define IMR_CONFLICT BIT(7) -#define IMR_UNREACH BIT(6) -#define IMR_PPOE BIT(5) -#define IMR_S3_INT BIT(3) -#define IMR_S2_INT BIT(2) -#define IMR_S1_INT BIT(1) -#define IMR_S0_INT BIT(0) - -/* Retry time, 1 = 100us */ -#define RTR0 0x0017 -#define RTR1 0x0018 - -/* Retry count register, default 0x08 */ -#define RCR 0x0019 - -/* rx memory size register, default 0x55, 2KB each socket */ -#define RMSR 0x001A - -/* tx memory size register, default 0x55 2kb each socket */ -#define TMSR 0x001B - -/* spi opcodes */ -#define OPCODE_WRITE 0xF0 -#define OPCODE_READ 0x0F - -/* Sockets */ -#define SOCKET0_BASE 0x0400 -#define SOCKET1_BASE 0x0500 -#define SOCKET2_BASE 0x0600 -#define SOCKET3_BASE 0x0700 - -/* socket register offsets */ -#define SN_MR 0x00 -#define SN_CR 0x01 -#define SN_IR 0x02 -#define SN_SR 0x03 -#define SN_PORT0 0x04 -#define SN_PORT1 0x05 -#define SN_DHAR0 0x06 -#define SN_DHAR1 0x07 -#define SN_DHAR2 0x08 -#define SN_DHAR3 0x09 -#define SN_DHAR4 0x0A -#define SN_DHAR5 0x0B -#define SN_DIPR0 0x0C -#define SN_DIPR1 0x0D -#define SN_DIPR2 0x0E -#define SN_DIPR3 0x0F -#define SN_DPORT0 0x10 -#define SN_DPORT1 0x11 -#define SN_MSSR0 0x12 -#define SN_MSSR1 0x13 -#define SN_PROTO 0x14 -#define SN_TOS 0x15 -#define SN_TTL 0x16 -#define SN_TX_FSR0 0x20 -#define SN_TX_FSR1 0x21 -#define SN_TX_RD0 0x22 -#define SN_TX_RD1 0x23 -#define SN_TX_WR0 0x24 -#define SN_TX_WR1 0x25 -#define SN_RX_RSR0 0x26 -#define SN_RX_RSR1 0x27 -#define SN_RX_RD0 0x28 -#define SN_RX_RD1 0x29 - -/* socket command codes */ -#define CR_OPEN 0x01 -#define CR_LISTEN 0x02 -#define CR_CONNECT 0x04 -#define CR_DISCON 0x08 -#define CR_CLOSE 0x10 -#define CR_SEND 0x20 -#define CR_SEND_MAC 0x21 -#define CR_SEND_KEEP 0x22 -#define CR_REC 0x40 - -/* socket status codes */ -#define SOCK_CLOSED 0x00 -#define SOCK_INIT 0x13 -#define SOCK_LISTEN 0x14 -#define SOCK_ESTABLISHED 0x17 -#define SOCK_CLOSE_WAIT 0x1C -#define SOCK_UDP 0x22 -#define SOCK_IPRAW 0x32 -#define SOCK_MACRAW 0x42 -#define SOCK_PPOE 0x5F - -/* socket changing status codes */ -#define SOCK_SYNSENT 0x15 -#define SOCK_SYNRECV 0x16 -#define SOCK_FIN_WAIT 0x18 -#define SOCK_CLOSING 0x1A -#define SOCK_TIME_WAIT 0x1B -#define SOCK_LAST_ACK 0x1D -#define SOCK_ARP 0x11 - -#define SOCK_ADDR(n, reg) ( \ - __builtin_constant_p(n) ? ( \ - (n == 0) ? (SOCKET0_BASE + reg) : \ - (n == 1) ? (SOCKET1_BASE + reg) : \ - (n == 2) ? (SOCKET2_BASE + reg) : \ - (n == 3) ? (SOCKET3_BASE + reg) : \ - 0xFF \ - ) : 0x00 \ -) - -#endif - 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
" + "analogInput(15): %u
" + "analogInput(16): %u
" + "analogInput(17): %u
" + "analogInput(18): %u
" + "analogInput(19): %u
" + "analogInput(20): %u
" + "analogInput(27): %u
" + "analogInput(28): %u
" + "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/w5100.h b/libraries/ethernet/w5100.h new file mode 100644 index 0000000..7f8c8b0 --- /dev/null +++ b/libraries/ethernet/w5100.h @@ -0,0 +1,181 @@ +/** + * @brief wiznet 5100 + */ + +#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 + +/* Gateway IP Address Register */ +#define GAR0 0x0001 +#define GAR1 0x0002 +#define GAR2 0x0003 +#define GAR3 0x0004 +#define GAR GAR0 + +/* Subnet mask register */ +#define SUBR0 0x0005 +#define SUBR1 0x0006 +#define SUBR2 0x0007 +#define SUBR3 0x0008 +#define SUBR SUBR0 + +/* Source Hardware Address Register */ +#define SHAR0 0x0009 +#define SHAR1 0x000A +#define SHAR2 0x000B +#define SHAR3 0x000C +#define SHAR4 0x000D +#define SHAR5 0x000E +#define SHAR SHAR0 + +/* Source IP Address register */ +#define SIPR0 0x000F +#define SIPR1 0x0010 +#define SIPR2 0x0011 +#define SIPR3 0x0012 +#define SIPR SIPR0 + +/* Interrupt register */ +#define IR 0x0015 +#define IR_CONFLICT BIT(7) +#define IR_UNREACH BIT(6) +#define IR_PPOE BIT(5) +#define IR_S3_INT BIT(3) +#define IR_S2_INT BIT(2) +#define IR_S1_INT BIT(1) +#define IR_S0_INT BIT(0) + +/* Interrupt mask register */ +#define IMR 0x0016 +#define IMR_CONFLICT BIT(7) +#define IMR_UNREACH BIT(6) +#define IMR_PPOE BIT(5) +#define IMR_S3_INT BIT(3) +#define IMR_S2_INT BIT(2) +#define IMR_S1_INT BIT(1) +#define IMR_S0_INT BIT(0) + +/* Retry time, 1 = 100us */ +#define RTR0 0x0017 +#define RTR1 0x0018 + +/* Retry count register, default 0x08 */ +#define RCR 0x0019 + +/* rx memory size register, default 0x55, 2KB each socket */ +#define RMSR 0x001A + +/* tx memory size register, default 0x55 2kb each socket */ +#define TMSR 0x001B + +/* spi opcodes */ +#define OPCODE_WRITE 0xF0 +#define OPCODE_READ 0x0F + +/* Sockets */ +#define SOCKET0_BASE 0x0400 +#define SOCKET1_BASE 0x0500 +#define SOCKET2_BASE 0x0600 +#define SOCKET3_BASE 0x0700 + +/* socket register offsets */ +#define SN_MR 0x00 +#define SN_CR 0x01 +#define SN_IR 0x02 +#define SN_SR 0x03 +#define SN_PORT0 0x04 +#define SN_PORT1 0x05 +#define SN_DHAR0 0x06 +#define SN_DHAR1 0x07 +#define SN_DHAR2 0x08 +#define SN_DHAR3 0x09 +#define SN_DHAR4 0x0A +#define SN_DHAR5 0x0B +#define SN_DIPR0 0x0C +#define SN_DIPR1 0x0D +#define SN_DIPR2 0x0E +#define SN_DIPR3 0x0F +#define SN_DPORT0 0x10 +#define SN_DPORT1 0x11 +#define SN_MSSR0 0x12 +#define SN_MSSR1 0x13 +#define SN_PROTO 0x14 +#define SN_TOS 0x15 +#define SN_TTL 0x16 +#define SN_TX_FSR0 0x20 +#define SN_TX_FSR1 0x21 +#define SN_TX_RD0 0x22 +#define SN_TX_RD1 0x23 +#define SN_TX_WR0 0x24 +#define SN_TX_WR1 0x25 +#define SN_RX_RSR0 0x26 +#define SN_RX_RSR1 0x27 +#define SN_RX_RD0 0x28 +#define SN_RX_RD1 0x29 + +/* socket command codes */ +#define CR_OPEN 0x01 +#define CR_LISTEN 0x02 +#define CR_CONNECT 0x04 +#define CR_DISCON 0x08 +#define CR_CLOSE 0x10 +#define CR_SEND 0x20 +#define CR_SEND_MAC 0x21 +#define CR_SEND_KEEP 0x22 +#define CR_REC 0x40 + +/* socket status codes */ +#define SOCK_CLOSED 0x00 +#define SOCK_INIT 0x13 +#define SOCK_LISTEN 0x14 +#define SOCK_ESTABLISHED 0x17 +#define SOCK_CLOSE_WAIT 0x1C +#define SOCK_UDP 0x22 +#define SOCK_IPRAW 0x32 +#define SOCK_MACRAW 0x42 +#define SOCK_PPOE 0x5F + +/* socket changing status codes */ +#define SOCK_SYNSENT 0x15 +#define SOCK_SYNRECV 0x16 +#define SOCK_FIN_WAIT 0x18 +#define SOCK_CLOSING 0x1A +#define SOCK_TIME_WAIT 0x1B +#define SOCK_LAST_ACK 0x1D +#define SOCK_ARP 0x11 + +#define SOCK_ADDR(n, reg) ( \ + __builtin_constant_p(n) ? ( \ + (n == 0) ? (SOCKET0_BASE + reg) : \ + (n == 1) ? (SOCKET1_BASE + reg) : \ + (n == 2) ? (SOCKET2_BASE + reg) : \ + (n == 3) ? (SOCKET3_BASE + reg) : \ + 0xFF \ + ) : 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 + -- cgit v1.2.3