1
0
mirror of https://github.com/arduino/Arduino.git synced 2024-11-30 11:24:12 +01:00

Backported Ethernet library from 1.5.x

This commit is contained in:
Cristian Maglie 2014-10-17 12:20:30 +02:00
parent 6ecb174c40
commit b9b0fcdadc
22 changed files with 348 additions and 265 deletions

4
libraries/Ethernet/Dhcp.cpp Executable file → Normal file
View File

@ -1,13 +1,13 @@
// DHCP Library v0.3 - April 25, 2009 // DHCP Library v0.3 - April 25, 2009
// Author: Jordan Terrell - blog.jordanterrell.com // Author: Jordan Terrell - blog.jordanterrell.com
#include "w5100.h" #include "utility/w5100.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "Dhcp.h" #include "Dhcp.h"
#include "Arduino.h" #include "Arduino.h"
#include "util.h" #include "utility/util.h"
int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout) int DhcpClass::beginWithDHCP(uint8_t *mac, unsigned long timeout, unsigned long responseTimeout)
{ {

0
libraries/Ethernet/Dhcp.h Executable file → Normal file
View File

View File

@ -2,9 +2,9 @@
// (c) Copyright 2009-2010 MCQN Ltd. // (c) Copyright 2009-2010 MCQN Ltd.
// Released under Apache License, version 2.0 // Released under Apache License, version 2.0
#include "w5100.h" #include "utility/w5100.h"
#include "EthernetUdp.h" #include "EthernetUdp.h"
#include "util.h" #include "utility/util.h"
#include "Dns.h" #include "Dns.h"
#include <string.h> #include <string.h>

View File

@ -1,4 +1,4 @@
#include "w5100.h" #include "utility/w5100.h"
#include "Ethernet.h" #include "Ethernet.h"
#include "Dhcp.h" #include "Dhcp.h"
@ -16,8 +16,10 @@ int EthernetClass::begin(uint8_t *mac_address)
// Initialise the basic info // Initialise the basic info
W5100.init(); W5100.init();
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.setMACAddress(mac_address); W5100.setMACAddress(mac_address);
W5100.setIPAddress(IPAddress(0,0,0,0).raw_address()); W5100.setIPAddress(IPAddress(0,0,0,0).raw_address());
SPI.endTransaction();
// Now try to get our config info from a DHCP server // Now try to get our config info from a DHCP server
int ret = _dhcp->beginWithDHCP(mac_address); int ret = _dhcp->beginWithDHCP(mac_address);
@ -25,9 +27,11 @@ int EthernetClass::begin(uint8_t *mac_address)
{ {
// We've successfully found a DHCP server and got our configuration info, so set things // We've successfully found a DHCP server and got our configuration info, so set things
// accordingly // accordingly
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.setIPAddress(_dhcp->getLocalIp().raw_address()); W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address()); W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address()); W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
SPI.endTransaction();
_dnsServerAddress = _dhcp->getDnsServerIp(); _dnsServerAddress = _dhcp->getDnsServerIp();
} }
@ -61,10 +65,12 @@ void EthernetClass::begin(uint8_t *mac_address, IPAddress local_ip, IPAddress dn
void EthernetClass::begin(uint8_t *mac, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet) void EthernetClass::begin(uint8_t *mac, IPAddress local_ip, IPAddress dns_server, IPAddress gateway, IPAddress subnet)
{ {
W5100.init(); W5100.init();
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.setMACAddress(mac); W5100.setMACAddress(mac);
W5100.setIPAddress(local_ip._address); W5100.setIPAddress(local_ip.raw_address());
W5100.setGatewayIp(gateway._address); W5100.setGatewayIp(gateway.raw_address());
W5100.setSubnetMask(subnet._address); W5100.setSubnetMask(subnet.raw_address());
SPI.endTransaction();
_dnsServerAddress = dns_server; _dnsServerAddress = dns_server;
} }
@ -80,9 +86,11 @@ int EthernetClass::maintain(){
case DHCP_CHECK_RENEW_OK: case DHCP_CHECK_RENEW_OK:
case DHCP_CHECK_REBIND_OK: case DHCP_CHECK_REBIND_OK:
//we might have got a new IP. //we might have got a new IP.
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.setIPAddress(_dhcp->getLocalIp().raw_address()); W5100.setIPAddress(_dhcp->getLocalIp().raw_address());
W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address()); W5100.setGatewayIp(_dhcp->getGatewayIp().raw_address());
W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address()); W5100.setSubnetMask(_dhcp->getSubnetMask().raw_address());
SPI.endTransaction();
_dnsServerAddress = _dhcp->getDnsServerIp(); _dnsServerAddress = _dhcp->getDnsServerIp();
break; break;
default: default:
@ -96,21 +104,27 @@ int EthernetClass::maintain(){
IPAddress EthernetClass::localIP() IPAddress EthernetClass::localIP()
{ {
IPAddress ret; IPAddress ret;
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.getIPAddress(ret.raw_address()); W5100.getIPAddress(ret.raw_address());
SPI.endTransaction();
return ret; return ret;
} }
IPAddress EthernetClass::subnetMask() IPAddress EthernetClass::subnetMask()
{ {
IPAddress ret; IPAddress ret;
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.getSubnetMask(ret.raw_address()); W5100.getSubnetMask(ret.raw_address());
SPI.endTransaction();
return ret; return ret;
} }
IPAddress EthernetClass::gatewayIP() IPAddress EthernetClass::gatewayIP()
{ {
IPAddress ret; IPAddress ret;
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.getGatewayIp(ret.raw_address()); W5100.getGatewayIp(ret.raw_address());
SPI.endTransaction();
return ret; return ret;
} }

View File

@ -1,5 +1,5 @@
#include "w5100.h" #include "utility/w5100.h"
#include "socket.h" #include "utility/socket.h"
extern "C" { extern "C" {
#include "string.h" #include "string.h"
@ -40,7 +40,7 @@ int EthernetClient::connect(IPAddress ip, uint16_t port) {
return 0; return 0;
for (int i = 0; i < MAX_SOCK_NUM; i++) { for (int i = 0; i < MAX_SOCK_NUM; i++) {
uint8_t s = W5100.readSnSR(i); uint8_t s = socketStatus(i);
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) { if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT || s == SnSR::CLOSE_WAIT) {
_sock = i; _sock = i;
break; break;
@ -88,7 +88,7 @@ size_t EthernetClient::write(const uint8_t *buf, size_t size) {
int EthernetClient::available() { int EthernetClient::available() {
if (_sock != MAX_SOCK_NUM) if (_sock != MAX_SOCK_NUM)
return W5100.getRXReceivedSize(_sock); return recvAvailable(_sock);
return 0; return 0;
} }
@ -120,8 +120,7 @@ int EthernetClient::peek() {
} }
void EthernetClient::flush() { void EthernetClient::flush() {
while (available()) ::flush(_sock);
read();
} }
void EthernetClient::stop() { void EthernetClient::stop() {
@ -154,7 +153,7 @@ uint8_t EthernetClient::connected() {
uint8_t EthernetClient::status() { uint8_t EthernetClient::status() {
if (_sock == MAX_SOCK_NUM) return SnSR::CLOSED; if (_sock == MAX_SOCK_NUM) return SnSR::CLOSED;
return W5100.readSnSR(_sock); return socketStatus(_sock);
} }
// the next function allows us to use the client returned by // the next function allows us to use the client returned by

View File

@ -1,5 +1,5 @@
#include "w5100.h" #include "utility/w5100.h"
#include "socket.h" #include "utility/socket.h"
extern "C" { extern "C" {
#include "string.h" #include "string.h"
} }

View File

@ -26,8 +26,8 @@
* bjoern@cs.stanford.edu 12/30/2008 * bjoern@cs.stanford.edu 12/30/2008
*/ */
#include "w5100.h" #include "utility/w5100.h"
#include "socket.h" #include "utility/socket.h"
#include "Ethernet.h" #include "Ethernet.h"
#include "Udp.h" #include "Udp.h"
#include "Dns.h" #include "Dns.h"
@ -41,7 +41,7 @@ uint8_t EthernetUDP::begin(uint16_t port) {
return 0; return 0;
for (int i = 0; i < MAX_SOCK_NUM; i++) { for (int i = 0; i < MAX_SOCK_NUM; i++) {
uint8_t s = W5100.readSnSR(i); uint8_t s = socketStatus(i);
if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) { if (s == SnSR::CLOSED || s == SnSR::FIN_WAIT) {
_sock = i; _sock = i;
break; break;
@ -120,7 +120,7 @@ int EthernetUDP::parsePacket()
// discard any remaining bytes in the last packet // discard any remaining bytes in the last packet
flush(); flush();
if (W5100.getRXReceivedSize(_sock) > 0) if (recvAvailable(_sock) > 0)
{ {
//HACK - hand-parse the UDP packet using TCP recv method //HACK - hand-parse the UDP packet using TCP recv method
uint8_t tmpBuf[8]; uint8_t tmpBuf[8];

View File

@ -29,7 +29,8 @@
// assign a MAC address for the ethernet controller. // assign a MAC address for the ethernet controller.
// fill in your address here: // fill in your address here:
byte mac[] = { byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
// assign an IP address for the controller: // assign an IP address for the controller:
IPAddress ip(192, 168, 1, 20); IPAddress ip(192, 168, 1, 20);
IPAddress gateway(192, 168, 1, 1); IPAddress gateway(192, 168, 1, 1);

View File

@ -24,7 +24,8 @@
// The IP address will be dependent on your local network. // The IP address will be dependent on your local network.
// gateway and subnet are optional: // gateway and subnet are optional:
byte mac[] = { byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177); IPAddress ip(192, 168, 1, 177);
IPAddress gateway(192, 168, 1, 1); IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0); IPAddress subnet(255, 255, 0, 0);

View File

@ -20,7 +20,8 @@
// Enter a MAC address for your controller below. // Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield // Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { byte mac[] = {
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02
};
// Initialize the Ethernet client library // Initialize the Ethernet client library
// with the IP address and port of the server // with the IP address and port of the server

View File

@ -25,7 +25,8 @@
// The IP address will be dependent on your local network. // The IP address will be dependent on your local network.
// gateway and subnet are optional: // gateway and subnet are optional:
byte mac[] = { byte mac[] = {
0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02 }; 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x02
};
IPAddress ip(192, 168, 1, 177); IPAddress ip(192, 168, 1, 177);
IPAddress gateway(192, 168, 1, 1); IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 0, 0); IPAddress subnet(255, 255, 0, 0);

View File

@ -24,7 +24,8 @@
// Enter a MAC address and IP address for your controller below. // Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network: // The IP address will be dependent on your local network:
byte mac[] = { byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177); IPAddress ip(192, 168, 1, 177);
// Enter the IP address of the server you're connecting to: // Enter the IP address of the server you're connecting to:

View File

@ -21,7 +21,8 @@
// Enter a MAC address and IP address for your controller below. // Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network: // The IP address will be dependent on your local network:
byte mac[] = { byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177); IPAddress ip(192, 168, 1, 177);
unsigned int localPort = 8888; // local port to listen on unsigned int localPort = 8888; // local port to listen on

View File

@ -7,13 +7,6 @@
For more on NTP time servers and the messages needed to communicate with them, For more on NTP time servers and the messages needed to communicate with them,
see http://en.wikipedia.org/wiki/Network_Time_Protocol see http://en.wikipedia.org/wiki/Network_Time_Protocol
Warning: NTP Servers are subject to temporary failure or IP address change.
Plese check
http://tf.nist.gov/tf-cgi/servers.cgi
if the time server used in the example didn't work.
created 4 Sep 2010 created 4 Sep 2010
by Michael Margolis by Michael Margolis
modified 9 Apr 2012 modified 9 Apr 2012
@ -30,13 +23,12 @@
// Enter a MAC address for your controller below. // Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield // Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
unsigned int localPort = 8888; // local port to listen for UDP packets unsigned int localPort = 8888; // local port to listen for UDP packets
IPAddress timeServer(132, 163, 4, 101); // time-a.timefreq.bldrdoc.gov NTP server char timeServer[] = "time.nist.gov"; // time.nist.gov NTP server
// IPAddress timeServer(132, 163, 4, 102); // time-b.timefreq.bldrdoc.gov NTP server
// IPAddress timeServer(132, 163, 4, 103); // time-c.timefreq.bldrdoc.gov NTP server
const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
@ -116,7 +108,7 @@ void loop()
} }
// send an NTP request to the time server at the given address // send an NTP request to the time server at the given address
unsigned long sendNTPpacket(IPAddress& address) unsigned long sendNTPpacket(char* address)
{ {
// set all bytes in the buffer to 0 // set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE); memset(packetBuffer, 0, NTP_PACKET_SIZE);

View File

@ -14,6 +14,8 @@
created 19 Apr 2012 created 19 Apr 2012
by Tom Igoe by Tom Igoe
modified 21 Jan 2014
by Federico Vanzati
http://arduino.cc/en/Tutorial/WebClientRepeating http://arduino.cc/en/Tutorial/WebClientRepeating
This code is in the public domain. This code is in the public domain.
@ -26,10 +28,11 @@
// assign a MAC address for the ethernet controller. // assign a MAC address for the ethernet controller.
// fill in your address here: // fill in your address here:
byte mac[] = { byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
// fill in an available IP address on your network here, // fill in an available IP address on your network here,
// for manual configuration: // for manual configuration:
IPAddress ip(10,0,0,20); IPAddress ip(192, 168, 1, 177);
// fill in your Domain Name Server address here: // fill in your Domain Name Server address here:
IPAddress myDns(1, 1, 1, 1); IPAddress myDns(1, 1, 1, 1);
@ -38,14 +41,19 @@ IPAddress myDns(1,1,1,1);
EthernetClient client; EthernetClient client;
char server[] = "www.arduino.cc"; char server[] = "www.arduino.cc";
//IPAddress server(64,131,82,241);
unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds
boolean lastConnected = false; // state of the connection last time through the main loop const unsigned long postingInterval = 10L * 1000L; // delay between updates, in milliseconds
const unsigned long postingInterval = 60*1000; // delay between updates, in milliseconds // the "L" is needed to use long type numbers
void setup() { void setup() {
// start serial port: // start serial port:
Serial.begin(9600); Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// give the ethernet module time to boot up: // give the ethernet module time to boot up:
delay(1000); delay(1000);
// start the Ethernet connection using a fixed IP address and DNS server: // start the Ethernet connection using a fixed IP address and DNS server:
@ -61,29 +69,23 @@ void loop() {
// purposes only: // purposes only:
if (client.available()) { if (client.available()) {
char c = client.read(); char c = client.read();
Serial.print(c); Serial.write(c);
} }
// if there's no net connection, but there was one last time // if ten seconds have passed since your last connection,
// through the loop, then stop the client: // then connect again and send data:
if (!client.connected() && lastConnected) { if (millis() - lastConnectionTime > postingInterval) {
Serial.println();
Serial.println("disconnecting.");
client.stop();
}
// if you're not connected, and ten seconds have passed since
// your last connection, then connect again and send data:
if(!client.connected() && (millis() - lastConnectionTime > postingInterval)) {
httpRequest(); httpRequest();
} }
// store the state of the connection for next time through
// the loop:
lastConnected = client.connected();
} }
// this method makes a HTTP connection to the server: // this method makes a HTTP connection to the server:
void httpRequest() { void httpRequest() {
// close any connection before send a new request.
// This will free the socket on the WiFi shield
client.stop();
// if there's a successful connection: // if there's a successful connection:
if (client.connect(server, 80)) { if (client.connect(server, 80)) {
Serial.println("connecting..."); Serial.println("connecting...");
@ -100,11 +102,7 @@ void httpRequest() {
else { else {
// if you couldn't make a connection: // if you couldn't make a connection:
Serial.println("connection failed"); Serial.println("connection failed");
Serial.println("disconnecting.");
client.stop();
} }
} }

View File

@ -21,7 +21,8 @@
// Enter a MAC address and IP address for your controller below. // Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network: // The IP address will be dependent on your local network:
byte mac[] = { byte mac[] = {
0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED
};
IPAddress ip(192, 168, 1, 177); IPAddress ip(192, 168, 1, 177);
// Initialize the Ethernet server library // Initialize the Ethernet server library

View File

@ -1,5 +1,5 @@
#include "w5100.h" #include "utility/w5100.h"
#include "socket.h" #include "utility/socket.h"
static uint16_t local_port; static uint16_t local_port;
@ -12,6 +12,7 @@ uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
if ((protocol == SnMR::TCP) || (protocol == SnMR::UDP) || (protocol == SnMR::IPRAW) || (protocol == SnMR::MACRAW) || (protocol == SnMR::PPPOE)) if ((protocol == SnMR::TCP) || (protocol == SnMR::UDP) || (protocol == SnMR::IPRAW) || (protocol == SnMR::MACRAW) || (protocol == SnMR::PPPOE))
{ {
close(s); close(s);
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.writeSnMR(s, protocol | flag); W5100.writeSnMR(s, protocol | flag);
if (port != 0) { if (port != 0) {
W5100.writeSnPORT(s, port); W5100.writeSnPORT(s, port);
@ -22,7 +23,7 @@ uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
} }
W5100.execCmdSn(s, Sock_OPEN); W5100.execCmdSn(s, Sock_OPEN);
SPI.endTransaction();
return 1; return 1;
} }
@ -30,13 +31,24 @@ uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag)
} }
uint8_t socketStatus(SOCKET s)
{
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
uint8_t status = W5100.readSnSR(s);
SPI.endTransaction();
return status;
}
/** /**
* @brief This function close the socket and parameter is "s" which represent the socket number * @brief This function close the socket and parameter is "s" which represent the socket number
*/ */
void close(SOCKET s) void close(SOCKET s)
{ {
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.execCmdSn(s, Sock_CLOSE); W5100.execCmdSn(s, Sock_CLOSE);
W5100.writeSnIR(s, 0xFF); W5100.writeSnIR(s, 0xFF);
SPI.endTransaction();
} }
@ -46,9 +58,13 @@ void close(SOCKET s)
*/ */
uint8_t listen(SOCKET s) uint8_t listen(SOCKET s)
{ {
if (W5100.readSnSR(s) != SnSR::INIT) SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
if (W5100.readSnSR(s) != SnSR::INIT) {
SPI.endTransaction();
return 0; return 0;
}
W5100.execCmdSn(s, Sock_LISTEN); W5100.execCmdSn(s, Sock_LISTEN);
SPI.endTransaction();
return 1; return 1;
} }
@ -70,9 +86,11 @@ uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port)
return 0; return 0;
// set destination IP // set destination IP
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.writeSnDIPR(s, addr); W5100.writeSnDIPR(s, addr);
W5100.writeSnDPORT(s, port); W5100.writeSnDPORT(s, port);
W5100.execCmdSn(s, Sock_CONNECT); W5100.execCmdSn(s, Sock_CONNECT);
SPI.endTransaction();
return 1; return 1;
} }
@ -85,7 +103,9 @@ uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port)
*/ */
void disconnect(SOCKET s) void disconnect(SOCKET s)
{ {
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.execCmdSn(s, Sock_DISCON); W5100.execCmdSn(s, Sock_DISCON);
SPI.endTransaction();
} }
@ -107,17 +127,21 @@ uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
// if freebuf is available, start. // if freebuf is available, start.
do do
{ {
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
freesize = W5100.getTXFreeSize(s); freesize = W5100.getTXFreeSize(s);
status = W5100.readSnSR(s); status = W5100.readSnSR(s);
SPI.endTransaction();
if ((status != SnSR::ESTABLISHED) && (status != SnSR::CLOSE_WAIT)) if ((status != SnSR::ESTABLISHED) && (status != SnSR::CLOSE_WAIT))
{ {
ret = 0; ret = 0;
break; break;
} }
yield();
} }
while (freesize < ret); while (freesize < ret);
// copy data // copy data
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.send_data_processing(s, (uint8_t *)buf, ret); W5100.send_data_processing(s, (uint8_t *)buf, ret);
W5100.execCmdSn(s, Sock_SEND); W5100.execCmdSn(s, Sock_SEND);
@ -127,12 +151,17 @@ uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
/* m2008.01 [bj] : reduce code */ /* m2008.01 [bj] : reduce code */
if ( W5100.readSnSR(s) == SnSR::CLOSED ) if ( W5100.readSnSR(s) == SnSR::CLOSED )
{ {
SPI.endTransaction();
close(s); close(s);
return 0; return 0;
} }
SPI.endTransaction();
yield();
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
} }
/* +2008.01 bj */ /* +2008.01 bj */
W5100.writeSnIR(s, SnIR::SEND_OK); W5100.writeSnIR(s, SnIR::SEND_OK);
SPI.endTransaction();
return ret; return ret;
} }
@ -146,6 +175,7 @@ uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len)
int16_t recv(SOCKET s, uint8_t *buf, int16_t len) int16_t recv(SOCKET s, uint8_t *buf, int16_t len)
{ {
// Check how much data is available // Check how much data is available
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
int16_t ret = W5100.getRXReceivedSize(s); int16_t ret = W5100.getRXReceivedSize(s);
if ( ret == 0 ) if ( ret == 0 )
{ {
@ -172,6 +202,16 @@ int16_t recv(SOCKET s, uint8_t *buf, int16_t len)
W5100.recv_data_processing(s, buf, ret); W5100.recv_data_processing(s, buf, ret);
W5100.execCmdSn(s, Sock_RECV); W5100.execCmdSn(s, Sock_RECV);
} }
SPI.endTransaction();
return ret;
}
int16_t recvAvailable(SOCKET s)
{
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
int16_t ret = W5100.getRXReceivedSize(s);
SPI.endTransaction();
return ret; return ret;
} }
@ -183,8 +223,9 @@ int16_t recv(SOCKET s, uint8_t *buf, int16_t len)
*/ */
uint16_t peek(SOCKET s, uint8_t *buf) uint16_t peek(SOCKET s, uint8_t *buf)
{ {
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.recv_data_processing(s, buf, 1, 1); W5100.recv_data_processing(s, buf, 1, 1);
SPI.endTransaction();
return 1; return 1;
} }
@ -213,6 +254,7 @@ uint16_t sendto(SOCKET s, const uint8_t *buf, uint16_t len, uint8_t *addr, uint1
} }
else else
{ {
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.writeSnDIPR(s, addr); W5100.writeSnDIPR(s, addr);
W5100.writeSnDPORT(s, port); W5100.writeSnDPORT(s, port);
@ -227,12 +269,17 @@ uint16_t sendto(SOCKET s, const uint8_t *buf, uint16_t len, uint8_t *addr, uint1
{ {
/* +2008.01 [bj]: clear interrupt */ /* +2008.01 [bj]: clear interrupt */
W5100.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT)); /* clear SEND_OK & TIMEOUT */ W5100.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT)); /* clear SEND_OK & TIMEOUT */
SPI.endTransaction();
return 0; return 0;
} }
SPI.endTransaction();
yield();
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
} }
/* +2008.01 bj */ /* +2008.01 bj */
W5100.writeSnIR(s, SnIR::SEND_OK); W5100.writeSnIR(s, SnIR::SEND_OK);
SPI.endTransaction();
} }
return ret; return ret;
} }
@ -252,11 +299,12 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t
if ( len > 0 ) if ( len > 0 )
{ {
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
ptr = W5100.readSnRX_RD(s); ptr = W5100.readSnRX_RD(s);
switch (W5100.readSnMR(s) & 0x07) switch (W5100.readSnMR(s) & 0x07)
{ {
case SnMR::UDP : case SnMR::UDP :
W5100.read_data(s, (uint8_t *)ptr, head, 0x08); W5100.read_data(s, ptr, head, 0x08);
ptr += 8; ptr += 8;
// read peer's IP address, port number. // read peer's IP address, port number.
addr[0] = head[0]; addr[0] = head[0];
@ -268,14 +316,14 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t
data_len = head[6]; data_len = head[6];
data_len = (data_len << 8) + head[7]; data_len = (data_len << 8) + head[7];
W5100.read_data(s, (uint8_t *)ptr, buf, data_len); // data copy. W5100.read_data(s, ptr, buf, data_len); // data copy.
ptr += data_len; ptr += data_len;
W5100.writeSnRX_RD(s, ptr); W5100.writeSnRX_RD(s, ptr);
break; break;
case SnMR::IPRAW : case SnMR::IPRAW :
W5100.read_data(s, (uint8_t *)ptr, head, 0x06); W5100.read_data(s, ptr, head, 0x06);
ptr += 6; ptr += 6;
addr[0] = head[0]; addr[0] = head[0];
@ -285,19 +333,19 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t
data_len = head[4]; data_len = head[4];
data_len = (data_len << 8) + head[5]; data_len = (data_len << 8) + head[5];
W5100.read_data(s, (uint8_t *)ptr, buf, data_len); // data copy. W5100.read_data(s, ptr, buf, data_len); // data copy.
ptr += data_len; ptr += data_len;
W5100.writeSnRX_RD(s, ptr); W5100.writeSnRX_RD(s, ptr);
break; break;
case SnMR::MACRAW: case SnMR::MACRAW:
W5100.read_data(s,(uint8_t*)ptr,head,2); W5100.read_data(s, ptr, head, 2);
ptr+=2; ptr+=2;
data_len = head[0]; data_len = head[0];
data_len = (data_len<<8) + head[1] - 2; data_len = (data_len<<8) + head[1] - 2;
W5100.read_data(s,(uint8_t*) ptr,buf,data_len); W5100.read_data(s, ptr, buf, data_len);
ptr += data_len; ptr += data_len;
W5100.writeSnRX_RD(s, ptr); W5100.writeSnRX_RD(s, ptr);
break; break;
@ -306,14 +354,20 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t
break; break;
} }
W5100.execCmdSn(s, Sock_RECV); W5100.execCmdSn(s, Sock_RECV);
SPI.endTransaction();
} }
return data_len; return data_len;
} }
/**
* @brief Wait for buffered transmission to complete.
*/
void flush(SOCKET s) {
// TODO
}
uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len) uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len)
{ {
uint8_t status=0;
uint16_t ret=0; uint16_t ret=0;
if (len > W5100.SSIZE) if (len > W5100.SSIZE)
@ -324,28 +378,34 @@ uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len)
if (ret == 0) if (ret == 0)
return 0; return 0;
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.send_data_processing(s, (uint8_t *)buf, ret); W5100.send_data_processing(s, (uint8_t *)buf, ret);
W5100.execCmdSn(s, Sock_SEND); W5100.execCmdSn(s, Sock_SEND);
while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK ) while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
{ {
status = W5100.readSnSR(s);
if (W5100.readSnIR(s) & SnIR::TIMEOUT) if (W5100.readSnIR(s) & SnIR::TIMEOUT)
{ {
/* in case of igmp, if send fails, then socket closed */ /* in case of igmp, if send fails, then socket closed */
/* if you want change, remove this code. */ /* if you want change, remove this code. */
SPI.endTransaction();
close(s); close(s);
return 0; return 0;
} }
SPI.endTransaction();
yield();
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
} }
W5100.writeSnIR(s, SnIR::SEND_OK); W5100.writeSnIR(s, SnIR::SEND_OK);
SPI.endTransaction();
return ret; return ret;
} }
uint16_t bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len) uint16_t bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len)
{ {
uint16_t ret =0; uint16_t ret =0;
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
if (len > W5100.getTXFreeSize(s)) if (len > W5100.getTXFreeSize(s))
{ {
ret = W5100.getTXFreeSize(s); // check size not to exceed MAX size. ret = W5100.getTXFreeSize(s); // check size not to exceed MAX size.
@ -355,6 +415,7 @@ uint16_t bufferData(SOCKET s, uint16_t offset, const uint8_t* buf, uint16_t len)
ret = len; ret = len;
} }
W5100.send_data_processing_offset(s, offset, buf, ret); W5100.send_data_processing_offset(s, offset, buf, ret);
SPI.endTransaction();
return ret; return ret;
} }
@ -370,14 +431,17 @@ int startUDP(SOCKET s, uint8_t* addr, uint16_t port)
} }
else else
{ {
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.writeSnDIPR(s, addr); W5100.writeSnDIPR(s, addr);
W5100.writeSnDPORT(s, port); W5100.writeSnDPORT(s, port);
SPI.endTransaction();
return 1; return 1;
} }
} }
int sendUDP(SOCKET s) int sendUDP(SOCKET s)
{ {
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
W5100.execCmdSn(s, Sock_SEND); W5100.execCmdSn(s, Sock_SEND);
/* +2008.01 bj */ /* +2008.01 bj */
@ -387,12 +451,17 @@ int sendUDP(SOCKET s)
{ {
/* +2008.01 [bj]: clear interrupt */ /* +2008.01 [bj]: clear interrupt */
W5100.writeSnIR(s, (SnIR::SEND_OK|SnIR::TIMEOUT)); W5100.writeSnIR(s, (SnIR::SEND_OK|SnIR::TIMEOUT));
SPI.endTransaction();
return 0; return 0;
} }
SPI.endTransaction();
yield();
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
} }
/* +2008.01 bj */ /* +2008.01 bj */
W5100.writeSnIR(s, SnIR::SEND_OK); W5100.writeSnIR(s, SnIR::SEND_OK);
SPI.endTransaction();
/* Sent ok */ /* Sent ok */
return 1; return 1;

5
libraries/Ethernet/utility/socket.h Executable file → Normal file
View File

@ -1,18 +1,21 @@
#ifndef _SOCKET_H_ #ifndef _SOCKET_H_
#define _SOCKET_H_ #define _SOCKET_H_
#include "w5100.h" #include "utility/w5100.h"
extern uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag); // Opens a socket(TCP or UDP or IP_RAW mode) extern uint8_t socket(SOCKET s, uint8_t protocol, uint16_t port, uint8_t flag); // Opens a socket(TCP or UDP or IP_RAW mode)
extern uint8_t socketStatus(SOCKET s);
extern void close(SOCKET s); // Close socket extern void close(SOCKET s); // Close socket
extern uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port); // Establish TCP connection (Active connection) extern uint8_t connect(SOCKET s, uint8_t * addr, uint16_t port); // Establish TCP connection (Active connection)
extern void disconnect(SOCKET s); // disconnect the connection extern void disconnect(SOCKET s); // disconnect the connection
extern uint8_t listen(SOCKET s); // Establish TCP connection (Passive connection) extern uint8_t listen(SOCKET s); // Establish TCP connection (Passive connection)
extern uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len); // Send data (TCP) extern uint16_t send(SOCKET s, const uint8_t * buf, uint16_t len); // Send data (TCP)
extern int16_t recv(SOCKET s, uint8_t * buf, int16_t len); // Receive data (TCP) extern int16_t recv(SOCKET s, uint8_t * buf, int16_t len); // Receive data (TCP)
extern int16_t recvAvailable(SOCKET s);
extern uint16_t peek(SOCKET s, uint8_t *buf); extern uint16_t peek(SOCKET s, uint8_t *buf);
extern uint16_t sendto(SOCKET s, const uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); // Send data (UDP/IP RAW) extern uint16_t sendto(SOCKET s, const uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t port); // Send data (UDP/IP RAW)
extern uint16_t recvfrom(SOCKET s, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); // Receive data (UDP/IP RAW) extern uint16_t recvfrom(SOCKET s, uint8_t * buf, uint16_t len, uint8_t * addr, uint16_t *port); // Receive data (UDP/IP RAW)
extern void flush(SOCKET s); // Wait for transmission to complete
extern uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len); extern uint16_t igmpsend(SOCKET s, const uint8_t * buf, uint16_t len);

View File

@ -1,7 +1,8 @@
#ifndef UTIL_H #ifndef UTIL_H
#define UTIL_H #define UTIL_H
#define htons(x) ( ((x)<<8) | (((x)>>8)&0xFF) ) #define htons(x) ( ((x)<< 8 & 0xFF00) | \
((x)>> 8 & 0x00FF) )
#define ntohs(x) htons(x) #define ntohs(x) htons(x)
#define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \ #define htonl(x) ( ((x)<<24 & 0xFF000000UL) | \

View File

@ -9,9 +9,8 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <avr/interrupt.h>
#include "w5100.h" #include "utility/w5100.h"
// W5100 controller instance // W5100 controller instance
W5100Class W5100; W5100Class W5100;
@ -29,10 +28,11 @@ void W5100Class::init(void)
SPI.begin(); SPI.begin();
initSS(); initSS();
SPI.beginTransaction(SPI_ETHERNET_SETTINGS);
writeMR(1<<RST); writeMR(1<<RST);
writeTMSR(0x55); writeTMSR(0x55);
writeRMSR(0x55); writeRMSR(0x55);
SPI.endTransaction();
for (int i=0; i<MAX_SOCK_NUM; i++) { for (int i=0; i<MAX_SOCK_NUM; i++) {
SBASE[i] = TXBUF_BASE + SSIZE * i; SBASE[i] = TXBUF_BASE + SSIZE * i;
@ -98,7 +98,7 @@ void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uin
{ {
uint16_t ptr; uint16_t ptr;
ptr = readSnRX_RD(s); ptr = readSnRX_RD(s);
read_data(s, (uint8_t *)ptr, data, len); read_data(s, ptr, data, len);
if (!peek) if (!peek)
{ {
ptr += len; ptr += len;
@ -106,13 +106,13 @@ void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uin
} }
} }
void W5100Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len) void W5100Class::read_data(SOCKET s, volatile uint16_t src, volatile uint8_t *dst, uint16_t len)
{ {
uint16_t size; uint16_t size;
uint16_t src_mask; uint16_t src_mask;
uint16_t src_ptr; uint16_t src_ptr;
src_mask = (uint16_t)src & RMASK; src_mask = src & RMASK;
src_ptr = RBASE[s] + src_mask; src_ptr = RBASE[s] + src_mask;
if( (src_mask + len) > RSIZE ) if( (src_mask + len) > RSIZE )

6
libraries/Ethernet/utility/w5100.h Executable file → Normal file
View File

@ -10,9 +10,10 @@
#ifndef W5100_H_INCLUDED #ifndef W5100_H_INCLUDED
#define W5100_H_INCLUDED #define W5100_H_INCLUDED
#include <avr/pgmspace.h>
#include <SPI.h> #include <SPI.h>
#define SPI_ETHERNET_SETTINGS SPISettings(4000000, MSBFIRST, SPI_MODE0)
#define MAX_SOCK_NUM 4 #define MAX_SOCK_NUM 4
typedef uint8_t SOCKET; typedef uint8_t SOCKET;
@ -138,7 +139,7 @@ public:
* the data from Receive buffer. Here also take care of the condition while it exceed * the data from Receive buffer. Here also take care of the condition while it exceed
* the Rx memory uper-bound of socket. * the Rx memory uper-bound of socket.
*/ */
void read_data(SOCKET s, volatile uint8_t * src, volatile uint8_t * dst, uint16_t len); void read_data(SOCKET s, volatile uint16_t src, volatile uint8_t * dst, uint16_t len);
/** /**
* @brief This function is being called by send() and sendto() function also. * @brief This function is being called by send() and sendto() function also.
@ -340,7 +341,6 @@ private:
inline static void setSS() { PORTB &= ~_BV(2); }; inline static void setSS() { PORTB &= ~_BV(2); };
inline static void resetSS() { PORTB |= _BV(2); }; inline static void resetSS() { PORTB |= _BV(2); };
#endif #endif
}; };
extern W5100Class W5100; extern W5100Class W5100;