Add the tidied up code from my Circuit Cellar design competition entry. This will be the new base for further development.

git-svn-id: svn+ssh://oldsvn/home/mlalondesvn/svn/cral@139 3ee9b42a-b53c-0410-a25e-f0b6218d5d5b
master
follower 17 years ago
parent 90daf297bd
commit 455c965626

@ -0,0 +1,4 @@
The original license of the WIZnet supplied vendor code is unknown.
The modifications and additions are licensed under the LGPL version 2 or later.

@ -0,0 +1,44 @@
WIZnet W5100 / WIZ810MJ Hardwired TCP/IP Ethernet Chip/Module Driver for Arduino
================================================================================
For more information see:
<http://code.rancidbacon.com/Netduino/>
Based on the W5100 driver from WIZnet.
Installation and Building
-------------------------
Arduino will compile the library automatically if you put the correct
files in the library directory of the Arduino application.
If you are installing this library you should put the files
from the directory named 'src/libw5100/' in the Arduino library directory.
It will be compiled automatically within the IDE.
For Arduino version 0010 the library directory location is:
<ARDUINO>/hardware/libraries/
For Ardino version 0009 the library directory location was:
<ARDUINO>/lib/targets/libraries/
If you want to compile the library manually you can use the following:
avr-gcc -mmcu=atmega168 -Wall -Os -fsigned-char -combine -c socket.c w5100.c -o wiz810mj.o
avr-strip --strip-debug --strip-unneeded -X -x *.o
Open a demo '.pde' to compile.
From the original driver README
-------------------------------
(You're almost certainly not going to need this.)
+ How to Change the interface mode
Change the value of the __DEF_IINCHIP_BUS__ in the types.h file.

@ -0,0 +1,144 @@
/*
IRC Bot demonstration
(May not function.)
*/
#include "libw5100.h"
#include "stream_connection.h"
void setup() {
/*
Setup function required by Arduino
*/
// Configure the network device
SpiConfiguration SPI = SpiConfiguration();
SPI.begin();
W5100Device W5100 = W5100Device(PIN_RESET);
NetworkInterface Network = NetworkInterface(W5100);
// You need to customise these to your own environment
Network.device.setIp(210,55,77,111);
Network.device.setMask(255,255,255,128);
Network.device.setGateway(210,55,77,1);
Serial.begin(9600);
randomSeed(analogRead(0));
// Rough state-machine to log on and process messages
// TODO: Implement DNS--This IP is irc.freenode.net
NetworkConnection conn = Network.connect(209,177,146,34, 6667);
Serial.println("Waiting to connect...");
while (!conn.isConnected()) {
delay(500);
}
Serial.println("Connected...");
int byteRead = -1;
int dataWait = 0;
StreamConnection stream = StreamConnection(conn);
// Change as needed
conn.print("NICK Arduino\n");
conn.print("USER Arduino 0 0 Arduino\n");
byte buf[4] = {0, 0, 0, 0};
int state = 0;
while (conn.isConnected()) {
if (stream.peekByte() >= 0) {
// New line
if (stream.peekByte() != ':') {
// Skip local responses/messages entirely. TODO: Handle PINGs?
while (stream.skipSegment("\x0A\x0D") < 0) {
// Ummm, we ran outta data--this screws things up...
// TODO: Have a time out?
delay(500);
}
} else {
if (state == 0) { // We've just connected
// Skip sending servername // TODO: Check it's the main one?
while (stream.skipSegment(" ") < 0) {
// Ummm, we ran outta data--this screws things up...
// TODO: Have a time out?
delay(500);
}
for (int idx=0; idx < 3; idx++) {
while (stream.peekByte() < 0) { // TODO: Time out?
delay(500);
}
buf[idx] = stream.readByte();
}
Serial.println((const char *) buf);
if (strcmp((const char *) buf, "376") == 0) { // End MOTD
state=1;
conn.print("JOIN #arduino\n");
}
} else if (state == 1) { // We've joined the channel, process messages.
// Skip sending servername // TODO: Check it's the main one?
while (stream.skipSegment(" ") < 0) {
// Ummm, we ran outta data--this screws things up...
// TODO: Have a time out?
delay(500);
}
// Look for messages addressed to us in the channel
if (stream.gobbleMatch(" ", "PRIVMSG") > 0) {
Serial.println("Matched PRIV MSG");
if (stream.gobbleMatch(" :", "#arduino") > 0) { // We treat the ":" as a separator too--does this break?
Serial.println("Matched #arduino");
// Check the message is to us...
if ((stream.peekByte() == 'A') && (stream.gobbleMatch(":", "Arduino") > 0)) {
Serial.println("Matched something");
// Give them something for their trouble...
if (random(1,3)==1) {
conn.print("PRIVMSG #arduino :Maybe.");
} else if (random(1,3)==1) {
conn.print("PRIVMSG #arduino :Probably.");
}
}
}
} else {
// No match
}
} else {
// Just skip this line
while ((byteRead = stream.readSegmentByte("\x0A\x0D")) >=0) {
Serial.print(byteRead, BYTE);
}
Serial.println("");
}
while (stream.skipSegment("\x0A\x0D") < 0) {
// Ummm, we ran outta data--this screws things up...
// TODO: Have a time out?
delay(500);
}
}
}
}
}
void loop() {
/*
Loop function required by Arduino
*/
}

@ -0,0 +1,137 @@
/*
Utility class to process data in a byte-wise manner without
requiring large memory buffers on the microcontroller.
*/
#include "stream_connection.h"
StreamConnection::StreamConnection(NetworkConnection& connection) : _connection (connection) {
/*
Initialise our one character buffer for the last character
read to indicate no character is currently buffered.
*/
_byteSeen = -1;
}
int StreamConnection::peekByte() {
/*
See what the next character will be without consuming it.
*/
if (_byteSeen < 0) {
if (_connection.available()) {
_byteSeen = _connection.read();
}
}
return _byteSeen;
}
int StreamConnection::readByte() {
/*
Read the next character, reffering to the buffer first if available,
consuming it in the process.
*/
int newByte = -1;
if (_byteSeen < 0) {
if (_connection.available()) {
newByte = _connection.read();
}
} else {
newByte = _byteSeen;
_byteSeen = -1;
}
return newByte;
}
int StreamConnection::readSegmentByte(const char * separators) {
/*
Read bytes until we encounter a separator, which we don't consume.
*/
// Blocks
while (peekByte() < 0) { // TODO: Time out?
delay(500);
}
if (!strchr(separators, peekByte())) {
return readByte();
}
return -1;
}
int StreamConnection::skipSegment(const char * separators) {
/*
Skip a segment between separators and the closing separators.
This enables us to skip to the end of a line for example.
*/
do {
if (peekByte() < 0) {
return -1;
}
// Skip everything not a separator
} while (!strchr(separators, peekByte()) && readByte());
do {
/* // We can't return here or we get stuck above.
if (peekByte() < 0) {
return -1;
}*/
while (peekByte() < 0) {
delay(500); // TODO: Time out?
}
// Skip everything that *is* a separator
} while (strchr(separators, peekByte()) && readByte());
return 1;
}
int StreamConnection::gobbleMatch(const char * separators, const char * target) {
/*
See if the next characters match the target string,
consuming characters in the process.
*/
int idx = 0;
int byteRead = -1;
while ((byteRead = readSegmentByte(separators)) >=0) {
if (idx < strlen(target)) {
if (byteRead != target[idx]) {
break;
}
idx++;
} else {
break;
}
}
if ((byteRead == -1) && (idx == strlen(target))) { // Matched
while (skipSegment(separators) < 0) {
// Ummm, we ran outta data--this screws things up...
// TODO: Have a time out?
delay(500);
}
return 1;
}
return -1;
}

@ -0,0 +1,29 @@
/*
Utility class to process data in a byte-wise manner without
requiring large memory buffers on the microcontroller.
*/
#ifndef _STREAM_CONNECTION_H_
#define _STREAM_CONNECTION_H_
#include "libw5100.h"
class StreamConnection {
public:
StreamConnection(NetworkConnection& connection);
int peekByte();
int readByte();
int skipSegment(const char * separators); // TODO: Return if separators found or not?
int readSegmentByte(const char * separators);
int debug;
int gobbleMatch(const char * separators, const char * target);
private:
NetworkConnection& _connection;
int _byteSeen;
};
#endif

@ -0,0 +1,69 @@
/*
Simple state machine-based Echo Server.
This could be used as the base for a more sophisticated server
that filtered the returned input, or altered state on the microcontroller
in response to the incoming data.
*/
#include "libw5100.h"
#include "echo_server.h"
#define ECHO_CONNECT_WAIT 0
#define ECHO_CONNECTED 1
#define ECHO_CLOSE 2
#define ECHO_HALT 3
EchoServer::EchoServer(int port) : _connection (NetworkConnection(port)) {
/*
Create a listening echo server on the requested port.
*/
_state = ECHO_CONNECT_WAIT;
_connection.listen(); // TODO: We should be using Network.listen(...) here and in initialisation list.
}
void EchoServer::next() {
/*
Process incoming data and return it to the sender.
*/
// TODO: Use better state machine implementation?
if (_state == ECHO_CONNECT_WAIT) {
if (_connection.isConnected()) {
_state = ECHO_CONNECTED;
} else {
// Keep waiting
}
} else if (_state == ECHO_CONNECTED) {
if (_connection.available()) {
_connection.print(_connection.read());
} else if (!_connection.isConnected()) {
// Data finished and client disconnected
_state == ECHO_CLOSE;
}
} else if (_state == ECHO_CLOSE) {
_connection.close();
_state = ECHO_HALT;
} else if (_state == ECHO_HALT) {
// Do nothing
} else {
// Unknown state, do nothing.
}
}

@ -0,0 +1,21 @@
/*
Simple state machine-based Echo Server.
*/
#ifndef _ECHO_SERVER_H_
#define _ECHO_SERVER_H_
class EchoServer {
public:
EchoServer(int port);
void next(); // TODO: Return something useful?
private:
NetworkConnection _connection; // TODO: Make public?
int _state;
};
#endif

@ -0,0 +1,45 @@
/*
Multi-connection Echo Server demonstration.
This demonstration currently only runs each server once.
*/
#include "libw5100.h"
#include "echo_server.h"
void setup() {
/*
Setup function required by Arduino
*/
// Configure the network device
SpiConfiguration SPI = SpiConfiguration();
SPI.begin();
W5100Device W5100 = W5100Device(PIN_RESET);
NetworkInterface Network = NetworkInterface(W5100);
// You need to customise these to your own environment
Network.device.setIp(210,55,77,111);
Network.device.setMask(255,255,255,128);
Network.device.setGateway(210,55,77,1);
// This uses the 1-argument constructor of EchoServer and supplies it with 7 for each instance.
EchoServer servers[MAX_SOCK_NUM] = {7, 7, 7, 7}; // This will break if MAX_SOCK_NUM changes.
while (1) {
for (int i=0; i<MAX_SOCK_NUM; i++) {
servers[i].next();
}
}
}
void loop() {
/*
Loop function required by Arduino
*/
}

@ -0,0 +1,60 @@
/*
Simple serial <--> network proxy demonstration.
*/
#include <libw5100.h>
void setup() {
/*
Setup function required by Arduino
*/
// Configure the network device
SpiConfiguration SPI = SpiConfiguration();
SPI.begin();
W5100Device W5100 = W5100Device(PIN_RESET);
NetworkInterface Network = NetworkInterface(W5100);
// You need to customise these to your own environment
Network.device.setIp(210,55,77,111);
Network.device.setMask(255,255,255,128);
Network.device.setGateway(210,55,77,1);
Serial.begin(9600); // Read the output in the Arduino serial monitor
while (1) {
NetworkConnection conn = Network.listen(7);
Serial.println("Waiting for client...");
while (!conn.isConnected()) {
delay(500);
}
Serial.println("Connected...");
while (conn.isConnected()) {
if (conn.available()) {
Serial.print(conn.read(), BYTE);
}
if (Serial.available()) {
conn.print(Serial.read());
}
}
conn.close();
Serial.println("Connection closed.");
}
}
void loop() {
/*
Loop function required by Arduino
*/
}

@ -0,0 +1,68 @@
/*
Sketch uploader / programmer demonstration
This demonstration requires a Bare Bones Freeduino or similar
Arduino-compatible board with an FTDI-USB cable connector.
Connect the target board to the programmer connector on
the Netduino shield.
Compile the sketch in Arduino as normal, press reset on the target
and then run the following command (on one line,
replace file names and IP):
<ARDUINO>/hardware/tools/avr/bin/avrdude
-C <ARDUINO>/hardware/tools/avr/etc/avrdude.conf
-pm168 -cstk500v1 -Pnet:192.168.2.105:7
-D -v -Uflash:w:/tmp/build31431.tmp/Blink_edit.hex:i
*/
#include "libw5100.h"
void setup() {
/*
Setup function required by Arduino
*/
// Configure the network device
SpiConfiguration SPI = SpiConfiguration();
SPI.begin();
W5100Device W5100 = W5100Device(PIN_RESET);
NetworkInterface Network = NetworkInterface(W5100);
// You need to customise these to your own environment
Network.device.setIp(210,55,77,111);
Network.device.setMask(255,255,255,128);
Network.device.setGateway(210,55,77,1);
Serial.begin(19200);
while (1) {
NetworkConnection conn = Network.listen(7);
while (!conn.isConnected()) {
delay(500);
}
while (conn.isConnected()) {
if (conn.available()) {
Serial.print(conn.read(), BYTE);
}
if (Serial.available()) {
conn.print(Serial.read());
}
}
conn.close();
}
}
void loop() {
/*
Loop function required by Arduino
*/
}

@ -0,0 +1,162 @@
/*
NetworkConnection
High level socket instance wrapper
*/
#include "connection.h"
int NetworkConnection::_nextSocket = 0;
NetworkConnection::NetworkConnection(uint16_t port) {
/*
Create the low-level socket this instance wraps (for server connections).
*/
_socket = _nextSocket; // TODO: Do properly (& max)
_nextSocket++;
socket(_socket, Sn_MR_TCP, port, 0);
}
NetworkConnection::NetworkConnection() {
/*
Create the low-level socket this instance wraps (for client connections).
*/
NetworkConnection(0);
}
int NetworkConnection::listen() { // TODO: Make private or protected?
/*
Start listening for a connection from a client.
*/
return !!::listen(_socket); // TODO: Use C++ namespaces for the driver functions?
}
int NetworkConnection::connect(uint8 * addr, uint16 port) { // TODO: Make private or protected?
/*
Client connection to a server.
*/
// TODO: Accept bytes here for addr?
int result = 0;
result = !!::connect(_socket, addr, port); // TODO: Use C++ namespaces for the driver functions?
return result;
}
int NetworkConnection::available() {
/*
Functionality matches 'Serial.available()'.
Note: If the socket is not connected then this will return 0,
but it is intended that 'isConnected()' would be checked first.
Returns:
"The number of bytes available to read ... or 0 if none are available.
If any data has come in, [...].available() will be greater than 0."
*/
// TODO: Do we want to check for 'isConnected' as well, or not?
// We have to, I guess, for valid behaviour with 'getSn_*'.
if (!isConnected()) {
return 0;
}
return getSn_RX_RSR(_socket);
}
#define NO_READ_DATA_AVAILABLE -1
int NetworkConnection::read() {
/*
Functionality matches 'Serial.read()'.
Returns:
"an int, the first byte of incoming serial data available
(or -1 if no data is available)."
Note: I thought 'recv' blocked until data was available,
but it currently seems not to block after all.
However, because I'm seeking to match the 'Serial.read'
behaviour we don't actually want to block anyway,
so we'll ignore it for the moment and handle things
ourself for now.
*/
uint8_t theByte;
if (!available()) {
return NO_READ_DATA_AVAILABLE;
}
recv(_socket, &theByte, 1);
return theByte;
}
int NetworkConnection::isConnected() {
/*
Returns true if the connection is established.
*/
// TODO: If we want the 'Network*' classes to be generic we
// would need to handle this differently:
return (getSn_SR(_socket) == SOCK_ESTABLISHED);
}
void NetworkConnection::print(uint8_t b) {
/*
Send a character over connection. Naming matches 'Serial' API.
*/
if (isConnected()) {
send(_socket, &b, 1);
} else {
// Just drop it if we're not connected.
}
}
void NetworkConnection::print(const char * text) {
/*
Send a string over connection. Naming matches 'Serial' API.
*/
for (unsigned int idx = 0; idx < strlen(text); idx++) {
print(text[idx]);
}
}
void NetworkConnection::close() {
/*
Close the connection.
*/
// TODO: Determine if we need/want the disconnect (see pg 26 W5100)
::close(_socket);
disconnect(_socket);
}

@ -0,0 +1,47 @@
/*
NetworkConnection
High level socket instance wrapper
*/
#ifndef _CONNECTION_H_
#define _CONNECTION_H_
// Required for use in Arduino environment
#include <WConstants.h>
// From original driver
#include "types.h"
#include "w5100.h"
#include "socket.h"
#include <string.h>
// TODO: Make this 'NetworkServerConnection'? Or just 'ServerConnection'?
// TODO: Pull one-line methods into class definition to allow inlining?
class NetworkConnection { // Essentially a Socket wrapper
public:
// TODO: Split into client/server connections? Subclass?
NetworkConnection(uint16_t port); // TODO: Add UDP, TCP choice? // For servers
NetworkConnection(); // For clients--is using the default constructor hide misuse? TODO: As above.
int listen();
int connect(uint8 * addr, uint16 port);
int isConnected();
int available();
int read();
void print(uint8_t);
void print(const char * text);
void close();
private:
SOCKET _socket;
static const int _MAX_SOCKETS = MAX_SOCK_NUM; // TODO: Use this.
static int _nextSocket;
};
#endif

@ -0,0 +1,99 @@
/*
Network Interface
Generic wrapper around a specific network device.
A Network Interface (representing the physical network device) returns a
connecting or listening Network Connection (representing a socket in either
client or server state).
*/
#include "interface.h"
#define HANDLE_BAD_ERROR() while (1) {};
NetworkInterface::NetworkInterface(W5100Device& networkDevice) : device (networkDevice) {
/*
Initialise the physical device with default network details.
Note: The "weirdness" in this function declaration is a "initalization list",
i.e. this bit:
) : device (networkDevice) {
it is needed to give the 'device' Reference a value supplied to the method
rather than having a new 'W5100Device' instance created.
*/
// This may not be the best place to do all this, but it'll do for now:
device.setMac(0x02,0xDE,0xAD,0xBE,0xEF,0x00);
device.setIp(169,254,254,169); // A local-link IP -- NOTE: This is out of spec.
device.setMask(255,255,0,0); // Matches local-link IP /16
device.setGateway(0,0,0,0); // We can't even guess this, so just skip it.
};
NetworkConnection NetworkInterface::listen(uint16_t port) {
/*
Start to listen for a request from a client.
NOTE: For reasons I don't understand, this FAILS TO WORK if port >255.
The port that gets opened is ~(port mod 255) but if you limit
port to be uint8_t for example you don't get an error until
the port number is bigger than 'long'.
TODO: Track and fix this for port numbers > 255.
Returns a NetworkConnection listening on the specified TCP port.
*/
NetworkConnection connection = NetworkConnection(port);
// TODO: How to best handle errors?
// There's two major categories I can think of currently:
// 1) A socket wasn't available to listen in the first place
// 2) The listen attempt failed for some reason
// Using 'HANDLE_BAD_ERROR()' (currently an infinite loop) is
// not ideal but should prevent the above errors slipping by unnoticed.
if (!connection.listen()) {
HANDLE_BAD_ERROR();
}
return connection;
}
NetworkConnection NetworkInterface::connect(byte b0, byte b1, byte b2, byte b3, uint16 port) {
/*
Connect to a server.
*/
NetworkConnection connection = NetworkConnection(4000);
byte _scratchBuffer[4]; // TODO: Move this?
// TODO: Better?
_scratchBuffer[0] = b0;
_scratchBuffer[1] = b1;
_scratchBuffer[2] = b2;
_scratchBuffer[3] = b3;
if (!connection.connect(_scratchBuffer, port)) {
HANDLE_BAD_ERROR();
}
return connection;
}
//#include "w5100_device.h"
//NetworkInterface Network = NetworkInterface(W5100);

@ -0,0 +1,27 @@
/*
Network Interface
Generic wrapper around a specific network device.
*/
#ifndef _INTERFACE_H_
#define _INTERFACE_H_
#include "w5100_device.h"
#include "connection.h"
// TODO?: Do we want to have a "default" socket accessible by 'Network.read()' etc?
class NetworkInterface {
public:
NetworkInterface(W5100Device& networkDevice);
NetworkConnection listen(uint16_t port);
NetworkConnection connect(byte b0, byte b1, byte b2, byte b3, uint16 port);
W5100Device& device; // TODO: Make this a generic "network device" interface
};
#endif

@ -0,0 +1,20 @@
/*
libw5100.h
*/
#ifndef _LIBW5100_H_
#define _LIBW5100_H_
// New object wrapper interface
#include "spi.h"
#include "w5100_device.h"
#include "connection.h"
#include "interface.h"
// TODO: Allow this to be changed in the main program, but use default otherwise.
// WIZnet module /RESET
#define PIN_RESET 9
#endif

@ -0,0 +1,484 @@
/*
*
@file socket.c
@brief setting chip register for socket
*
*/
#include <avr/io.h>
#include <avr/interrupt.h>
#include "types.h"
#ifdef __DEF_IINCHIP_DBG__
#include <stdio.h>
#endif
#include "w5100.h"
#include "socket.h"
static uint16 local_port;
/**
@brief This Socket function initialize the channel in perticular mode, and set the port and wait for W5100 done it.
@return 1 for sucess else 0.
*/
uint8 socket(
SOCKET s, /**< for socket number */
uint8 protocol, /**< for socket protocol */
uint16 port, /**< the source port for the socket */
uint8 flag /**< the option for the socket */
)
{
uint8 ret;
#ifdef __DEF_IINCHIP_DBG__
printf("socket()\r\n");
#endif
if ((protocol == Sn_MR_TCP) || (protocol == Sn_MR_UDP) || (protocol == Sn_MR_IPRAW) || (protocol == Sn_MR_MACRAW) || (protocol == Sn_MR_PPPOE))
{
close(s);
IINCHIP_WRITE(Sn_MR(s),protocol | flag);
if (port != 0) {
IINCHIP_WRITE(Sn_PORT0(s),(uint8)((port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(port & 0x00ff));
} else {
local_port++; // if don't set the source port, set local_port number.
IINCHIP_WRITE(Sn_PORT0(s),(uint8)((local_port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_PORT0(s) + 1),(uint8)(local_port & 0x00ff));
}
IINCHIP_WRITE(Sn_CR(s),Sn_CR_OPEN); // run sockinit Sn_CR
ret = 1;
}
else
{
ret = 0;
}
#ifdef __DEF_IINCHIP_DBG__
printf("Sn_SR = %.2x , Protocol = %.2x\r\n", IINCHIP_READ(Sn_SR(s)), IINCHIP_READ(Sn_MR(s)));
#endif
return ret;
}
/**
@brief This function close the socket and parameter is "s" which represent the socket number
*/
void close(SOCKET s)
{
#ifdef __DEF_IINCHIP_DBG__
printf("close()\r\n");
#endif
IINCHIP_WRITE(Sn_CR(s),Sn_CR_CLOSE);
}
/**
@brief This function established the connection for the channel in passive (server) mode. This function waits for the request from the peer.
@return 1 for success else 0.
*/
uint8 listen(
SOCKET s /**< the socket number */
)
{
uint8 ret;
#ifdef __DEF_IINCHIP_DBG__
printf("listen()\r\n");
#endif
if (IINCHIP_READ(Sn_SR(s)) == SOCK_INIT)
{
IINCHIP_WRITE(Sn_CR(s),Sn_CR_LISTEN);
ret = 1;
}
else
{
ret = 0;
#ifdef __DEF_IINCHIP_DBG__
printf("Fail[invalid ip,port]\r\n");
#endif
}
return ret;
}
/**
@brief This function established the connection for the channel in Active (client) mode.
This function waits for the untill the connection is established.
@return 1 for success else 0.
*/
uint8 connect(SOCKET s, uint8 * addr, uint16 port)
{
uint8 ret;
#ifdef __DEF_IINCHIP_DBG__
printf("connect()\r\n");
#endif
if
(
((addr[0] == 0xFF) && (addr[1] == 0xFF) && (addr[2] == 0xFF) && (addr[3] == 0xFF)) ||
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
(port == 0x00)
)
{
ret = 0;
#ifdef __DEF_IINCHIP_DBG__
printf("Fail[invalid ip,port]\r\n");
#endif
}
else
{
ret = 1;
// set destination IP
IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
IINCHIP_WRITE(Sn_CR(s),Sn_CR_CONNECT);
// wait for completion
while (IINCHIP_READ(Sn_CR(s)))
{
if (IINCHIP_READ(Sn_SR(s)) == SOCK_CLOSED)
{
#ifdef __DEF_IINCHIP_DBG__
printf("SOCK_CLOSED.\r\n");
#endif
ret = 0; break;
}
}
}
return ret;
}
/**
@brief This function used for disconnect the socket and parameter is "s" which represent the socket number
@return 1 for success else 0.
*/
void disconnect(SOCKET s)
{
#ifdef __DEF_IINCHIP_DBG__
printf("disconnect()\r\n");
#endif
IINCHIP_WRITE(Sn_CR(s),Sn_CR_DISCON);
}
/**
@brief This function used to send the data in TCP mode
@return 1 for success else 0.
*/
uint16 send(
SOCKET s, /**< the socket index */
const uint8 * buf, /**< a pointer to data */
uint16 len /**< the data size to be send */
)
{
uint8 status=0;
uint16 ret=0;
uint16 freesize=0;
#ifdef __DEF_IINCHIP_DBG__
printf("send()\r\n");
#endif
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else ret = len;
// if freebuf is available, start.
do
{
freesize = getSn_TX_FSR(s);
status = IINCHIP_READ(Sn_SR(s));
if ((status != SOCK_ESTABLISHED) && (status != SOCK_CLOSE_WAIT))
{
ret = 0;
break;
}
#ifdef __DEF_IINCHIP_DBG__
printf("socket %d freesize(%d) empty or error\r\n", s, freesize);
#endif
} while (freesize < ret);
// copy data
send_data_processing(s, (uint8 *)buf, ret);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
// wait for completion
while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
{
status = IINCHIP_READ(Sn_SR(s));
if (status == SOCK_CLOSED)
{
#ifdef __DEF_IINCHIP_DBG__
printf("SOCK_CLOSED.\r\n");
#endif
putISR(s, getISR(s) & (Sn_IR_RECV | Sn_IR_DISCON | Sn_IR_CON));
IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT));
return 0;
}
}
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
return ret;
}
/**
@brief This function is an application I/F function which is used to receive the data in TCP mode.
It continues to wait for data as much as the application wants to receive.
@return received data size for success else -1.
*/
uint16 recv(
SOCKET s, /**< socket index */
uint8 * buf, /**< a pointer to copy the data to be received */
uint16 len /**< the data size to be read */
)
{
uint16 ret=0;
#ifdef __DEF_IINCHIP_DBG__
printf("recv()\r\n");
#endif
if ( len > 0 )
{
recv_data_processing(s, buf, len);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
ret = len;
}
return ret;
}
/**
@brief This function is an application I/F function which is used to send the data for other then TCP mode.
Unlike TCP transmission, The peer's destination address and the port is needed.
@return This function return send data size for success else -1.
*/
uint16 sendto(
SOCKET s, /**< socket index */
const uint8 * buf, /**< a pointer to the data */
uint16 len, /**< the data size to send */
uint8 * addr, /**< the peer's Destination IP address */
uint16 port /**< the peer's destination port number */
)
{
uint8 status=0;
uint8 isr=0;
uint16 ret=0;
#ifdef __DEF_IINCHIP_DBG__
printf("sendto()\r\n");
#endif
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else ret = len;
if
(
((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
((port == 0x00)) ||(ret == 0)
)
{
;
#ifdef __DEF_IINCHIP_DBG__
printf("%d Fail[%.2x.%.2x.%.2x.%.2x, %.d, %d]\r\n",s, addr[0], addr[1], addr[2], addr[3] , port, len);
printf("Fail[invalid ip,port]\r\n");
#endif
}
else
{
IINCHIP_WRITE(Sn_DIPR0(s),addr[0]);
IINCHIP_WRITE((Sn_DIPR0(s) + 1),addr[1]);
IINCHIP_WRITE((Sn_DIPR0(s) + 2),addr[2]);
IINCHIP_WRITE((Sn_DIPR0(s) + 3),addr[3]);
IINCHIP_WRITE(Sn_DPORT0(s),(uint8)((port & 0xff00) >> 8));
IINCHIP_WRITE((Sn_DPORT0(s) + 1),(uint8)(port & 0x00ff));
// copy data
send_data_processing(s, (uint8 *)buf, ret);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
while ( (IINCHIP_READ(Sn_IR(s)) & Sn_IR_SEND_OK) != Sn_IR_SEND_OK )
{
status = IINCHIP_READ(Sn_SR(s));
#ifndef __DEF_IINCHIP_INT__
isr = IINCHIP_READ(Sn_IR(s));
#endif
if ((isr & Sn_IR_TIMEOUT) || (getISR(s) & Sn_IR_TIMEOUT))
{
#ifdef __DEF_IINCHIP_DBG__
printf("send fail.\r\n");
#endif
putISR(s, getISR(s) & (Sn_IR_RECV | Sn_IR_DISCON | Sn_IR_CON)); /* clear SEND_OK & TIMEOUT in I_STATUS[s] */
IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT)); // clear SEND_OK & TIMEOUT in Sn_IR(s)
return 0;
}
}
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
}
return ret;
}
/**
@brief This function is an application I/F function which is used to receive the data in other then
TCP mode. This function is used to receive UDP, IP_RAW and MAC_RAW mode, and handle the header as well.
@return This function return received data size for success else -1.
*/
uint16 recvfrom(
SOCKET s, /**< the socket number */
uint8 * buf, /**< a pointer to copy the data to be received */
uint16 len, /**< the data size to read */
uint8 * addr, /**< a pointer to store the peer's IP address */
uint16 *port /**< a pointer to store the peer's port number. */
)
{
uint8 head[8];
uint16 data_len=0;
uint16 ptr=0;
#ifdef __DEF_IINCHIP_DBG__
printf("recvfrom()\r\n");
#endif
if ( len > 0 )
{
ptr = IINCHIP_READ(Sn_RX_RD0(s));
ptr = ((ptr & 0x00ff) << 8) + IINCHIP_READ(Sn_RX_RD0(s) + 1);
#ifdef __DEF_IINCHIP_DBG__
printf("ISR_RX: rd_ptr : %.4x\r\n", ptr);
#endif
switch (IINCHIP_READ(Sn_MR(s)) & 0x07)
{
case Sn_MR_UDP :
read_data(s, (uint8 *)ptr, head, 0x08);
ptr += 8;
// read peer's IP address, port number.
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
*port = head[4];
*port = (*port << 8) + head[5];
data_len = head[6];
data_len = (data_len << 8) + head[7];
#ifdef __DEF_IINCHIP_DBG__
printf("UDP msg arrived\r\n");
printf("source Port : %d\r\n", *port);
printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
#endif
read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
ptr += data_len;
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
break;
case Sn_MR_IPRAW :
read_data(s, (uint8 *)ptr, head, 0x06);
ptr += 6;
addr[0] = head[0];
addr[1] = head[1];
addr[2] = head[2];
addr[3] = head[3];
data_len = head[4];
data_len = (data_len << 8) + head[5];
#ifdef __DEF_IINCHIP_DBG__
printf("IP RAW msg arrived\r\n");
printf("source IP : %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]);
#endif
read_data(s, (uint8 *)ptr, buf, data_len); // data copy.
ptr += data_len;
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
break;
case Sn_MR_MACRAW :
read_data(s,(uint8*)ptr,head,2);
ptr+=2;
data_len = head[0];
data_len = (data_len<<8) + head[1] - 2;
read_data(s,(uint8*) ptr,buf,data_len);
ptr += data_len;
IINCHIP_WRITE(Sn_RX_RD0(s),(uint8)((ptr & 0xff00) >> 8));
IINCHIP_WRITE((Sn_RX_RD0(s) + 1),(uint8)(ptr & 0x00ff));
#ifdef __DEF_IINCHIP_DGB__
printf("MAC RAW msg arrived\r\n");
printf("dest mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);
printf("src mac=%.2X.%.2X.%.2X.%.2X.%.2X.%.2X\r\n",buf[6],buf[7],buf[8],buf[9],buf[10],buf[11]);
printf("type =%.2X%.2X\r\n",buf[12],buf[13]);
#endif
break;
default :
break;
}
IINCHIP_WRITE(Sn_CR(s),Sn_CR_RECV);
}
#ifdef __DEF_IINCHIP_DBG__
printf("recvfrom() end ..\r\n");
#endif
return data_len;
}
uint16 igmpsend(SOCKET s, const uint8 * buf, uint16 len)
{
//uint8 status=0;
uint8 isr=0;
uint16 ret=0;
#ifdef __DEF_IINCHIP_DBG__
printf("igmpsend()\r\n");
#endif
if (len > getIINCHIP_TxMAX(s)) ret = getIINCHIP_TxMAX(s); // check size not to exceed MAX size.
else ret = len;
if (ret == 0)
{
;
#ifdef __DEF_IINCHIP_DBG__
//printf("%d Fail[%d]\r\n",len);
#endif
}
else
{
// copy data
send_data_processing(s, (uint8 *)buf, ret);
IINCHIP_WRITE(Sn_CR(s),Sn_CR_SEND);
while (IINCHIP_READ(Sn_CR(s)))
{
// status = IINCHIP_READ(Sn_SR(s));
#ifndef __DEF_IINCHIP_INT__
isr = IINCHIP_READ(Sn_IR(s));
#endif
if ((getISR(s) & Sn_IR_TIMEOUT) || (isr & Sn_IR_TIMEOUT))
{
#ifdef __DEF_IINCHIP_DBG__
printf("igmpsend fail.\r\n");
#endif
putISR(s, getISR(s) & (Sn_IR_RECV | Sn_IR_DISCON | Sn_IR_CON));
IINCHIP_WRITE(Sn_IR(s), (Sn_IR_SEND_OK | Sn_IR_TIMEOUT));
return 0;
}
}
putISR(s, getISR(s) & (~Sn_IR_SEND_OK));
IINCHIP_WRITE(Sn_IR(s), Sn_IR_SEND_OK);
}
return ret;
}

@ -0,0 +1,32 @@
/*
*
@file socket.h
@brief define function of socket API
*
*/
#ifndef _SOCKET_H_
#define _SOCKET_H_
#ifdef __cplusplus
extern "C" {
#endif
extern uint8 socket(SOCKET s, uint8 protocol, uint16 port, uint8 flag); // Opens a socket(TCP or UDP or IP_RAW mode)
extern void close(SOCKET s); // Close socket
extern uint8 connect(SOCKET s, uint8 * addr, uint16 port); // Establish TCP connection (Active connection)
extern void disconnect(SOCKET s); // disconnect the connection
extern uint8 listen(SOCKET s); // Establish TCP connection (Passive connection)
extern uint16 send(SOCKET s, const uint8 * buf, uint16 len); // Send data (TCP)
extern uint16 recv(SOCKET s, uint8 * buf, uint16 len); // Receive data (TCP)
extern uint16 sendto(SOCKET s, const uint8 * buf, uint16 len, uint8 * addr, uint16 port); // Send data (UDP/IP RAW)
extern uint16 recvfrom(SOCKET s, uint8 * buf, uint16 len, uint8 * addr, uint16 *port); // Receive data (UDP/IP RAW)
extern uint16 igmpsend(SOCKET s, const uint8 * buf, uint16 len);
#ifdef __cplusplus
} // extern "C"
#endif
#endif
/* _SOCKET_H_ */

@ -0,0 +1,60 @@
/*
SPI Configuration
TODO: Enable multiple SPI devices to be controlled.
*/
#include "spi.h"
SpiConfiguration::SpiConfiguration() {
// begin();
}
void SpiConfiguration::begin(void) {
/*
Configure pins and registers required for SPI communication.
*/
// Configure I/O pins
pinMode(PIN_DATA_OUT, OUTPUT);
pinMode(PIN_DATA_IN, INPUT);
pinMode(PIN_SPI_CLOCK, OUTPUT);
pinMode(PIN_SLAVE_SELECT, OUTPUT);
digitalWrite(PIN_SLAVE_SELECT, HIGH); // Disable slave
/*
Configure SPI Control Register (SPCR) (All values initially 0)
Bit Description
7 SPI Interrupt Enable -- disable (SPIE --> 0)
6 SPI Enable -- enable (SPE --> 1)
5 Data Order -- MSB 1st (DORD --> 0) (Slave specific)
4 Master/Slave Select -- master (MSTR --> 1)
3 Clock Polarity -- (CPOL --> 0) (Slave specific) ("Mode")
2 Clock Phase -- (CPHA --> 0) (Slave specific)
1 SPI Clock Rate Select 1 -- } (SPR1 --> 0)
0 SPI Clock Rate Select 0 -- } fOSC/4 (SPR0 --> 0) ("Fastest" but see SPI2X in SPSR)
*/
SPCR = (1<<SPE)| (1<<MSTR);
// Clear previous data and status (TODO: Determine if necessary/better way.)
// (Based on Arduino Playground SPI example.)
byte dummy;
dummy = SPSR;
dummy = SPDR;
delay(10);
}
/*
Instantiate a 'SPI' object to be used in a manner consistent with
the way the Arduino environment handles serial configuration with the
'Serial'/'HardwareSerial' object/class combination.
*/
SpiConfiguration SPI = SpiConfiguration();

@ -0,0 +1,35 @@
/*
SPI Configuration
*/
#ifndef _SPI_H_
#define _SPI_H_
// Define SPI-related pins
#define PIN_DATA_OUT 11 // MOSI (Master Out / Slave In)
#define PIN_DATA_IN 12 // MISO (Master In / Slave Out)
#define PIN_SPI_CLOCK 13 // SCK (Serial Clock)
// TODO: Define this elsewhere as this is specific to the network module.
#define PIN_SLAVE_SELECT 10 // SS (Slave Select)
// Required for use in Arduino environment
#include <WConstants.h>
class SpiConfiguration {
/*
Handles SPI configuration with an API consistent
with the style of existing Arduino 'HardwareSerial' class.
Needs to be used before SPI functionality is accessed.
*/
public:
SpiConfiguration();
void begin(void);
};
#endif

@ -0,0 +1,194 @@
/*
*
@file type.h
*
*/
#ifndef _TYPE_H_
#define _TYPE_H_
/***************************************************
* attribute for mcu ( types, ... )
***************************************************/
//#include "mcu_define.h"
#define __ARDUINO__ 1
#define __MCU_AVR__ 1
#define __MCU_TYPE__ __MCU_AVR__
// TODO: We should really specify the Chip Select pin based on
// the MCU rather than the platform.
#ifdef __ARDUINO__
#define CS_PIN (1 << PB2)
#endif
//---- Refer "Rom File Maker Manual Vx.x.pdf"
#include <avr/pgmspace.h>
#define _ENDIAN_LITTLE_ 0 /**< This must be defined if system is little-endian alignment */
#define _ENDIAN_BIG_ 1
#define SYSTEM_ENDIAN _ENDIAN_LITTLE_
#define MAX_SOCK_NUM 4 /**< Maxmium number of socket */
#define CLK_CPU 8000000 /**< 8Mhz(for serial) */
/* ## __DEF_IINCHIP_xxx__ : define option for iinchip driver *****************/
#ifndef __ARDUINO__
#define __DEF_IINCHIP_DBG__ /* involve debug code in driver (socket.c) */
#define __DEF_IINCHIP_INT__ /**< involve interrupt service routine (socket.c) */
#define __DEF_IINCHIP_PPP__ /* involve pppoe routine (socket.c) */
/* If it is defined, the source files (md5.h,md5.c) must
be included in your project.
Otherwise, the source files must be removed from your
project. */
#endif
#define __DEF_IINCHIP_DIRECT_MODE__ 1
#define __DEF_IINCHIP_INDIRECT_MODE__ 2
#define __DEF_IINCHIP_SPI_MODE__ 3
//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_DIRECT_MODE__
//#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_INDIRECT_MODE__
#define __DEF_IINCHIP_BUS__ __DEF_IINCHIP_SPI_MODE__ /*Enable SPI_mode*/
/**
@brief __DEF_IINCHIP_MAP_xxx__ : define memory map for iinchip
*/
#define __DEF_IINCHIP_MAP_BASE__ 0x8000
#if (__DEF_IINCHIP_BUS__ == __DEF_IINCHIP_DIRECT_MODE__)
#define COMMON_BASE __DEF_IINCHIP_MAP_BASE__
#else
#define COMMON_BASE 0x0000
#endif
#define __DEF_IINCHIP_MAP_TXBUF__ (COMMON_BASE + 0x4000) /* Internal Tx buffer address of the iinchip */
#define __DEF_IINCHIP_MAP_RXBUF__ (COMMON_BASE + 0x6000) /* Internal Rx buffer address of the iinchip */
#if (__MCU_TYPE__ == __MCU_AVR__)
#ifdef __DEF_IINCHIP_INT__
// iinchip use external interrupt 4
#define IINCHIP_ISR_DISABLE() (EIMSK &= ~(0x10))
#define IINCHIP_ISR_ENABLE() (EIMSK |= 0x10)
#define IINCHIP_ISR_GET(X) (X = EIMSK)
#define IINCHIP_ISR_SET(X) (EIMSK = X)
#else
#define IINCHIP_ISR_DISABLE()
#define IINCHIP_ISR_ENABLE()
#define IINCHIP_ISR_GET(X)
#define IINCHIP_ISR_SET(X)
#endif
#else
#error "unknown MCU type"
#endif
/* gcc version */
/* WinAVR-20050214-install.exe */
#define __WINAVR_20050214__ 0
#define __WINAVR_20060125__ 1
#define __WINAVR_20060421__ 2
/* #define __COMPILER_VERSION__ __WINAVR_20060421__ // <- move makefile*/
#if (__COMPILER_VERSION__ == __WINAVR_20050214__)
#ifndef __STDIO_FDEVOPEN_COMPAT_12
#define __STDIO_FDEVOPEN_COMPAT_12
#endif
#endif
#ifndef NULL
#define NULL ((void *) 0)
#endif
#ifndef __ARDUINO__
typedef enum { false, true } bool;
#endif
#ifndef _SIZE_T
#define _SIZE_T
typedef unsigned int size_t;
#endif
/**
* The 8-bit signed data type.
*/
typedef char int8;
/**
* The volatile 8-bit signed data type.
*/
typedef volatile char vint8;
/**
* The 8-bit unsigned data type.
*/
typedef unsigned char uint8;
/**
* The volatile 8-bit unsigned data type.
*/
typedef volatile unsigned char vuint8;
/**
* The 16-bit signed data type.
*/
typedef int int16;
/**
* The volatile 16-bit signed data type.
*/
typedef volatile int vint16;
/**
* The 16-bit unsigned data type.
*/
typedef unsigned int uint16;
/**
* The volatile 16-bit unsigned data type.
*/
typedef volatile unsigned int vuint16;
/**
* The 32-bit signed data type.
*/
typedef long int32;
/**
* The volatile 32-bit signed data type.
*/
typedef volatile long vint32;
/**
* The 32-bit unsigned data type.
*/
typedef unsigned long uint32;
/**
* The volatile 32-bit unsigned data type.
*/
typedef volatile unsigned long vuint32;
/* bsd */
typedef uint8 u_char; /**< 8-bit value */
typedef uint8 SOCKET;
typedef uint16 u_short; /**< 16-bit value */
typedef uint16 u_int; /**< 16-bit value */
typedef uint32 u_long; /**< 32-bit value */
typedef union _un_l2cval {
u_long lVal;
u_char cVal[4];
}un_l2cval;
typedef union _un_i2cval {
u_int iVal;
u_char cVal[2];
}un_i2cval;
/** global define */
#define FW_VERSION 0x01000001 /**< System F/W Version(test) : 0.0.0.1 */
#define HW_PM_VERSION "0.1"
#define HW_NM_VERSION "0.1"
#define HW_MB_VERSION "0.1"
#define TX_RX_MAX_BUF_SIZE 2048
#define TX_BUF 0x1100
#define RX_BUF (TX_BUF+TX_RX_MAX_BUF_SIZE)
#define UART_DEVICE_CNT 1 /**< UART device number */
/* #define SUPPORT_UART_ONE */
#endif /* _TYPE_H_ */

File diff suppressed because it is too large Load Diff

@ -0,0 +1,312 @@
/*
@file w5100.h
*/
#ifndef _W5100_H_
#define _W5100_H_
#define MR __DEF_IINCHIP_MAP_BASE__
#define IDM_OR ((__DEF_IINCHIP_MAP_BASE__ + 0x00))
#define IDM_AR0 ((__DEF_IINCHIP_MAP_BASE__ + 0x01))
#define IDM_AR1 ((__DEF_IINCHIP_MAP_BASE__ + 0x02))
#define IDM_DR ((__DEF_IINCHIP_MAP_BASE__ + 0x03))
/**
@brief Gateway IP Register address
*/
#define GAR0 (COMMON_BASE + 0x0001)
/**
@brief Subnet mask Register address
*/
#define SUBR0 (COMMON_BASE + 0x0005)
/**
@brief Source MAC Register address
*/
#define SHAR0 (COMMON_BASE + 0x0009)
/**
@brief Source IP Register address
*/
#define SIPR0 (COMMON_BASE + 0x000F)
/**
@brief Interrupt Register
*/
#define IR (COMMON_BASE + 0x0015)
/**
@brief Interrupt mask register
*/
#define IMR (COMMON_BASE + 0x0016)
/**
@brief Timeout register address( 1 is 100us )
*/
#define RTR0 (COMMON_BASE + 0x0017)
/**
@brief Retry count reigster
*/
#define RCR (COMMON_BASE + 0x0019)
/**
@brief Receive memory size reigster
*/
#define RMSR (COMMON_BASE + 0x001A)
/**
@brief Transmit memory size reigster
*/
#define TMSR (COMMON_BASE + 0x001B)
/**
@brief Authentication type register address in PPPoE mode
*/
#define PATR0 (COMMON_BASE + 0x001C)
//#define PPPALGO (COMMON_BASE + 0x001D)
#define PTIMER (COMMON_BASE + 0x0028)
#define PMAGIC (COMMON_BASE + 0x0029)
/**
@brief Unreachable IP register address in UDP mode
*/
#define UIPR0 (COMMON_BASE + 0x002A)
/**
@brief Unreachable Port register address in UDP mode
*/
#define UPORT0 (COMMON_BASE + 0x002E)
/**
@brief socket register
*/
#define CH_BASE (COMMON_BASE + 0x0400)
/**
@brief size of each channel register map
*/
#define CH_SIZE 0x0100
/**
@brief socket Mode register
*/
#define Sn_MR(ch) (CH_BASE + ch * CH_SIZE + 0x0000)
/**
@brief channel Sn_CR register
*/
#define Sn_CR(ch) (CH_BASE + ch * CH_SIZE + 0x0001)
/**
@brief channel interrupt register
*/
#define Sn_IR(ch) (CH_BASE + ch * CH_SIZE + 0x0002)
/**
@brief channel status register
*/
#define Sn_SR(ch) (CH_BASE + ch * CH_SIZE + 0x0003)
/**
@brief source port register
*/
#define Sn_PORT0(ch) (CH_BASE + ch * CH_SIZE + 0x0004)
/**
@brief Peer MAC register address
*/
#define Sn_DHAR0(ch) (CH_BASE + ch * CH_SIZE + 0x0006)
/**
@brief Peer IP register address
*/
#define Sn_DIPR0(ch) (CH_BASE + ch * CH_SIZE + 0x000C)
/**
@brief Peer port register address
*/
#define Sn_DPORT0(ch) (CH_BASE + ch * CH_SIZE + 0x0010)
/**
@brief Maximum Segment Size(Sn_MSSR0) register address
*/
#define Sn_MSSR0(ch) (CH_BASE + ch * CH_SIZE + 0x0012)
/**
@brief Protocol of IP Header field register in IP raw mode
*/
#define Sn_PROTO(ch) (CH_BASE + ch * CH_SIZE + 0x0014)
/**
@brief IP Type of Service(TOS) Register
*/
#define Sn_TOS(ch) (CH_BASE + ch * CH_SIZE + 0x0015)
/**
@brief IP Time to live(TTL) Register
*/
#define Sn_TTL(ch) (CH_BASE + ch * CH_SIZE + 0x0016)
//not support
//#define RX_CH_DMEM_SIZE (COMMON_BASE + 0x001E)
//#define TX_CH_DMEM_SIZE (COMMON_BASE + 0x001F)
/**
@brief Transmit free memory size register
*/
#define Sn_TX_FSR0(ch) (CH_BASE + ch * CH_SIZE + 0x0020)
/**
@brief Transmit memory read pointer register address
*/
#define Sn_TX_RD0(ch) (CH_BASE + ch * CH_SIZE + 0x0022)
/**
@brief Transmit memory write pointer register address
*/
#define Sn_TX_WR0(ch) (CH_BASE + ch * CH_SIZE + 0x0024)
/**
@brief Received data size register
*/
#define Sn_RX_RSR0(ch) (CH_BASE + ch * CH_SIZE + 0x0026)
/**
@brief Read point of Receive memory
*/
#define Sn_RX_RD0(ch) (CH_BASE + ch * CH_SIZE + 0x0028)
/**
@brief Write point of Receive memory
*/
#define Sn_RX_WR0(ch) (CH_BASE + ch * CH_SIZE + 0x002A)
/* MODE register values */
#define MR_RST 0x80 /**< reset */
#define MR_PB 0x10 /**< ping block */
#define MR_PPPOE 0x08 /**< enable pppoe */
#define MR_LB 0x04 /**< little or big endian selector in indirect mode */
#define MR_AI 0x02 /**< auto-increment in indirect mode */
#define MR_IND 0x01 /**< enable indirect mode */
/* IR register values */
#define IR_CONFLICT 0x80 /**< check ip confict */
#define IR_UNREACH 0x40 /**< get the destination unreachable message in UDP sending */
#define IR_PPPoE 0x20 /**< get the PPPoE close message */
#define IR_SOCK(ch) (0x01 << ch) /**< check socket interrupt */
/* Sn_MR values */
#define Sn_MR_CLOSE 0x00 /**< unused socket */
#define Sn_MR_TCP 0x01 /**< TCP */
#define Sn_MR_UDP 0x02 /**< UDP */
#define Sn_MR_IPRAW 0x03 /**< IP LAYER RAW SOCK */
#define Sn_MR_MACRAW 0x04 /**< MAC LAYER RAW SOCK */
#define Sn_MR_PPPOE 0x05 /**< PPPoE */
#define Sn_MR_ND 0x20 /**< No Delayed Ack(TCP) flag */
#define Sn_MR_MULTI 0x80 /**< support multicating */
/* Sn_CR values */
#define Sn_CR_OPEN 0x01 /**< initialize or open socket */
#define Sn_CR_LISTEN 0x02 /**< wait connection request in tcp mode(Server mode) */
#define Sn_CR_CONNECT 0x04 /**< send connection request in tcp mode(Client mode) */
#define Sn_CR_DISCON 0x08 /**< send closing reqeuset in tcp mode */
#define Sn_CR_CLOSE 0x10 /**< close socket */
#define Sn_CR_SEND 0x20 /**< updata txbuf pointer, send data */
#define Sn_CR_SEND_MAC 0x21 /**< send data with MAC address, so without ARP process */
#define Sn_CR_SEND_KEEP 0x22 /**< send keep alive message */
#define Sn_CR_RECV 0x40 /**< update rxbuf pointer, recv data */
#ifdef __DEF_IINCHIP_PPP__
#define Sn_CR_PCON 0x23
#define Sn_CR_PDISCON 0x24
#define Sn_CR_PCR 0x25
#define Sn_CR_PCN 0x26
#define Sn_CR_PCJ 0x27
#endif
/* Sn_IR values */
#ifdef __DEF_IINCHIP_PPP__
#define Sn_IR_PRECV 0x80
#define Sn_IR_PFAIL 0x40
#define Sn_IR_PNEXT 0x20
#endif
#define Sn_IR_SEND_OK 0x10 /**< complete sending */
#define Sn_IR_TIMEOUT 0x08 /**< assert timeout */
#define Sn_IR_RECV 0x04 /**< receiving data */
#define Sn_IR_DISCON 0x02 /**< closed socket */
#define Sn_IR_CON 0x01 /**< established connection */
/* Sn_SR values */
#define SOCK_CLOSED 0x00 /**< closed */
#define SOCK_INIT 0x13 /**< init state */
#define SOCK_LISTEN 0x14 /**< listen state */
#define SOCK_SYNSENT 0x15 /**< connection state */
#define SOCK_SYNRECV 0x16 /**< connection state */
#define SOCK_ESTABLISHED 0x17 /**< success to connect */
#define SOCK_FIN_WAIT 0x18 /**< closing state */
#define SOCK_CLOSING 0x1A /**< closing state */
#define SOCK_TIME_WAIT 0x1B /**< closing state */
#define SOCK_CLOSE_WAIT 0x1C /**< closing state */
#define SOCK_LAST_ACK 0x1D /**< closing state */
#define SOCK_UDP 0x22 /**< udp socket */
#define SOCK_IPRAW 0x32 /**< ip raw mode socket */
#define SOCK_MACRAW 0x42 /**< mac raw mode socket */
#define SOCK_PPPOE 0x5F /**< pppoe socket */
/* IP PROTOCOL */
#define IPPROTO_IP 0 /**< Dummy for IP */
#define IPPROTO_ICMP 1 /**< Control message protocol */
#define IPPROTO_IGMP 2 /**< Internet group management protocol */
#define IPPROTO_GGP 3 /**< Gateway^2 (deprecated) */
#define IPPROTO_TCP 6 /**< TCP */
#define IPPROTO_PUP 12 /**< PUP */
#define IPPROTO_UDP 17 /**< UDP */
#define IPPROTO_IDP 22 /**< XNS idp */
#define IPPROTO_ND 77 /**< UNOFFICIAL net disk protocol */
#define IPPROTO_RAW 255 /**< Raw IP packet */
/*********************************************************
* iinchip access function
*********************************************************/
#ifdef __cplusplus
extern "C" {
#endif
extern uint8 IINCHIP_READ(uint16 addr);
extern uint8 IINCHIP_WRITE(uint16 addr,uint8 data);
extern uint16 wiz_read_buf(uint16 addr, uint8* buf,uint16 len);
extern uint16 wiz_write_buf(uint16 addr,uint8* buf,uint16 len);
extern void iinchip_init(void); // reset iinchip
extern void sysinit(uint8 tx_size, uint8 rx_size); // setting tx/rx buf size
extern uint8 getISR(uint8 s);
extern void putISR(uint8 s, uint8 val);
extern uint16 getIINCHIP_RxMAX(uint8 s);
extern uint16 getIINCHIP_TxMAX(uint8 s);
extern uint16 getIINCHIP_RxMASK(uint8 s);
extern uint16 getIINCHIP_TxMASK(uint8 s);
extern uint16 getIINCHIP_RxBASE(uint8 s);
extern uint16 getIINCHIP_TxBASE(uint8 s);
extern void setGAR(uint8 * addr); // set gateway address
extern void setSUBR(uint8 * addr); // set subnet mask address
extern void setSHAR(uint8 * addr); // set local MAC address
extern void setSIPR(uint8 * addr); // set local IP address
extern void setRTR(uint16 timeout); // set retry duration for data transmission, connection, closing ...
extern void setRCR(uint8 retry); // set retry count (above the value, assert timeout interrupt)
extern void setIMR(uint8 mask); // set interrupt mask.
extern void getGAR(uint8 * addr);
extern void getSUBR(uint8 * addr);
extern void getSHAR(uint8 * addr);
extern void getSIPR(uint8 * addr);
extern uint8 getIR( void );
extern void setSn_MSS(SOCKET s, uint16 Sn_MSSR0); // set maximum segment size
extern void setSn_PROTO(SOCKET s, uint8 proto); // set IP Protocol value using IP-Raw mode
extern uint8 getSn_IR(SOCKET s); // get socket interrupt status
extern uint8 getSn_SR(SOCKET s); // get socket status
extern uint16 getSn_TX_FSR(SOCKET s); // get socket TX free buf size
extern uint16 getSn_RX_RSR(SOCKET s); // get socket RX recv buf size
extern void setSn_DHAR(SOCKET s, uint8 * addr);
extern void setSn_DIPR(SOCKET s, uint8 * addr);
extern void setSn_DPORT(SOCKET s, uint8 * addr);
extern void getSn_DHAR(SOCKET s, uint8 * addr);
extern void getSn_DIPR(SOCKET s, uint8 * addr);
extern void getSn_DPORT(SOCKET s, uint8 * addr);
extern void setSn_TTL(SOCKET s, uint8 ttl);
extern void setMR(uint8 val);
#ifdef __DEF_IINCHIP_PPP__
extern uint8 pppinit(uint8 *id, uint8 idlen, uint8 *passwd, uint8 passwdlen);
extern uint8 pppterm(uint8 *mac,uint8 *sessionid);
#endif
extern void send_data_processing(SOCKET s, uint8 *data, uint16 len);
extern void recv_data_processing(SOCKET s, uint8 *data, uint16 len);
extern void read_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len);
extern void write_data(SOCKET s, vuint8 * src, vuint8 * dst, uint16 len);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

@ -0,0 +1,140 @@
/*
W5100 device configuration
*/
#include "w5100_device.h"
W5100Device::W5100Device(int resetPin) {
/*
Store configuration and initialise the W5100 device
*/
// TODO: We should really allow the chip-select pin to be set here?
// Or require that it's defined. (Currently in the library file 'types.h'.)
_resetPin = resetPin;
_init();
}
void W5100Device::_init(void) {
/*
Initialise the W5100 device and driver.
*/
/*
Initialise the W5100 chip
(Originally I thought it was possible for the chip
to function without a hardware reset but it
seems not to be the case.)
*/
pinMode(_resetPin, OUTPUT);
// We rely on the time between function calls to
// be long enough for the chip to recognise the
// reset.
digitalWrite(_resetPin, HIGH);
digitalWrite(_resetPin, LOW); // reset
digitalWrite(_resetPin, HIGH);
// Enable SPI bug fix
// (We only need to do this to enable additional optional
// devices on the SPI bus. The current version of the W5100
// requires SPI_EN to be low when you communicate with other
// devices on the SPI bus.)
#define PIN_SPI_EN 8 // WIZnet module SPI_EN
pinMode(PIN_SPI_EN, OUTPUT);
digitalWrite(PIN_SPI_EN, HIGH);
// Chip initialisation by driver
// Might be redundant following the above reset,
// as this performs a software reset.
iinchip_init();
// Initialise driver
// (This is required to configure some variables used
// internally by the driver--even if the default chip
// configuration is used.)
sysinit(0x55, 0x55);
}
byte * W5100Device::_packBuffer(byte b0, byte b1, byte b2, byte b3) {
/*
Utility function to pack four bytes into a buffer
in order to pass on to the lower-level drive functions.
*/
return _packBuffer(b0, b1, b2, b3, 0, 0); // Adds two bytes of padding
}
byte * W5100Device::_packBuffer(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5) {
/*
Utility function to pack six bytes into a buffer
in order to pass on to the lower-level drive functions.
*/
_scratchBuffer[0] = b0;
_scratchBuffer[1] = b1;
_scratchBuffer[2] = b2;
_scratchBuffer[3] = b3;
_scratchBuffer[4] = b4;
_scratchBuffer[5] = b5;
return _scratchBuffer;
}
void W5100Device::setIp(byte b0, byte b1, byte b2, byte b3) {
/*
Set device IP address.
*/
setSIPR(_packBuffer(b0, b1, b2, b3));
}
void W5100Device::setMask(byte b0, byte b1, byte b2, byte b3) {
/*
Set device net mask.
*/
setSUBR(_packBuffer(b0, b1, b2, b3));
}
void W5100Device::setGateway(byte b0, byte b1, byte b2, byte b3) {
/*
Set device gateway.
(Note: this is required to access the internet from within a LAN.)
*/
setGAR(_packBuffer(b0, b1, b2, b3));
}
void W5100Device::setMac(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5) {
/*
Set device MAC address.
*/
setSHAR(_packBuffer(b0, b1, b2, b3, b4, b5));
}
// W5100Device W5100 = W5100Device(PIN_RESET);

@ -0,0 +1,39 @@
/*
W5100 device configuration
*/
#ifndef _W5100_DEVICE_H_
#define _W5100_DEVICE_H_
// From original driver
#include "types.h"
#include "w5100.h"
#include "socket.h"
// Required for use in Arduino environment
#include <WConstants.h>
class W5100Device {
public:
W5100Device(int resetPin);
void setIp(byte b0, byte b1, byte b2, byte b3);
void setMask(byte b0, byte b1, byte b2, byte b3);
void setGateway(byte b0, byte b1, byte b2, byte b3);
void setMac(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5);
void _init(void);
private:
byte * _packBuffer(byte b0, byte b1, byte b2, byte b3);
byte * _packBuffer(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5);
int _resetPin;
byte _scratchBuffer[6]; // TODO: Can we make this static?
};
#endif
Loading…
Cancel
Save