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-f0b6218d5d5bmaster
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…
Reference in new issue