Btw, my RFM12B to Ethernet bridge is already working reliable on breadboard. I'm currently pushing received wireless data to a Redis server over Ethernet. Look like I'll have to order some more Teensy 3.0's soon ;-)
I don't use Eagle, so no, sorry, no Eagle files.
Here is a newer version via OSH Park design sharing.
http://oshpark.com/shared_projects/LOt9A5hs
That first board lacked a way to reset the W5200, which really turned out to be necessary. This newer one connects the reset to pin 9. If you order some of these from OSH Park, please let me know when they arrive. I'll try to gid up the experimental code for it...
The minimum output capacitance required to maintain stability is 33 uF (this value may be increased without
limit). Larger values of output capacitance will give improved transient response.
ESR LIMITS:
The ESR of the output capacitor will cause loop instability if it is too high or too low. The acceptable range of
ESR plotted versus load current is shown in Figure 19. It is essential that the output capacitor meet these
requirements, or oscillations can result.
In porting stuff to/from Arduino, check for anything using 'int' and 'unsigned' types (as opposed to int16_t, uint32_t, etc.). The int data type on Arduino is 16 bits, while it is 32-bits on Arm based processor. For other code, you would want to check for 'double' as well, but I doubt ethernet uses double. Also, check for anything to do with interrupts and direct port manipulation. If the code has been ported to the Due (look for #ifdef __SAM3X8E__), that code probably is a reasonable starting off place for the Teensy 3.0. Finally, PROGMEM usage might need to be adjusted.I breadboarded the Teensy 3.0 and WIZ820io, copied the w5100.cpp and w5100.h files to the /libraries/Ethernet/utility directory and loaded the WebServer.ino file from the ethernet examples directory. I also added a reset to the WIZ820io using digital pin 9. When I went to compile using Teensyduino release 1.15, I got some errors. I then downloaded the Teensyduino 1.16 release and installed it, and the compile completed successfully, but the webserver address was not correct, ie, not the address that I had selected. I then tried the DHCP address printer example, and it could not connect using DHCP.
... copied the w5100.cpp and w5100.h files to the /libraries/Ethernet/utility directory and loaded the WebServer.ino file from the ethernet examples directory. .... I got some errors. I then downloaded the Teensyduino 1.16 release and installed it, and the compile completed successfully, but the webserver address was not correct, ie, not the address that I had selected. I then tried the DHCP address printer example, and it could not connect using DHCP.
/*
Web Server
A simple web server that shows the value of the analog input pins.
using an Arduino Wiznet Ethernet shield.
Circuit:
* Ethernet shield attached to pins 10, 11, 12, 13
* Analog inputs attached to pins A0 through A5 (optional)
created 18 Dec 2009
by David A. Mellis
modified 9 Apr 2012
by Tom Igoe
*/
#include <SPI.h>
#include <Ethernet.h>
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
0xDE, 0xAD, 0xBA, 0xBE, 0xFA, 0xCE };
IPAddress ip(192,168,1,135);
// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(115200);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
// reset the WIZ812mj nic
pinMode(9, OUTPUT);
digitalWrite(9, LOW);
delay(250);
digitalWrite(9, HIGH);
delay(1000);
// start the Ethernet connection and the server:
Ethernet.begin(mac, ip);
server.begin();
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
}
void loop() {
// listen for incoming clients
EthernetClient client = server.available();
if (client) {
Serial.println("new client");
// an http request ends with a blank line
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) {
char c = client.read();
Serial.write(c);
// if you've gotten to the end of the line (received a newline
// character) and the line is blank, the http request has ended,
// so you can send a reply
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println(F("HTTP/1.1 200 OK"));
client.println(F("Content-Type: text/html"));
client.println(F("Connection: close")); // the connection will be closed after completion of the response
client.println(F("Refresh: 5")); // refresh the page automatically every 5 sec
client.println(F(""));
client.println(F("<!DOCTYPE HTML>"));
client.println(F("<html>"));
// output the value of each analog input pin
for (int analogChannel = 0; analogChannel < 6; analogChannel++) {
int sensorReading = analogRead(analogChannel);
client.print(F("BoogerHead "));
client.print(analogChannel);
client.print(F(" is "));
client.print(sensorReading);
client.println(F("<br />"));
}
client.println(F("</html>"));
break;
}
if (c == '\n') {
// you're starting a new line
currentLineIsBlank = true;
}
else if (c != '\r') {
// you've gotten a character on the current line
currentLineIsBlank = false;
}
}
}
// give the web browser time to receive the data
delay(1);
// close the connection:
client.stop();
Serial.println("client disonnected");
}
}
/*
* Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#include <stdio.h>
#include <string.h>
#include <avr/interrupt.h>
#include "w5100.h"
// W5100 controller instance
W5100Class W5100;
#define TX_RX_MAX_BUF_SIZE 2048
#define TX_BUF 0x1100
#define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE)
#ifdef W5200
#define TXBUF_BASE 0x8000
#define RXBUF_BASE 0xC000
#else
#define TXBUF_BASE 0x4000
#define RXBUF_BASE 0x6000
#endif
void W5100Class::init(void)
{
delay(300);
SPI.begin();
initSS();
writeMR(1<<RST);
#ifdef W5200
for (int i=0; i<MAX_SOCK_NUM; i++) {
write((0x4000 + i * 0x100 + 0x001F), 2);
write((0x4000 + i * 0x100 + 0x001E), 2);
}
#else
writeTMSR(0x55);
writeRMSR(0x55);
#endif
for (int i=0; i<MAX_SOCK_NUM; i++) {
SBASE[i] = TXBUF_BASE + SSIZE * i;
RBASE[i] = RXBUF_BASE + RSIZE * i;
}
}
uint16_t W5100Class::getTXFreeSize(SOCKET s)
{
uint16_t val=0, val1=0;
do {
val1 = readSnTX_FSR(s);
if (val1 != 0)
val = readSnTX_FSR(s);
}
while (val != val1);
return val;
}
uint16_t W5100Class::getRXReceivedSize(SOCKET s)
{
uint16_t val=0,val1=0;
do {
val1 = readSnRX_RSR(s);
if (val1 != 0)
val = readSnRX_RSR(s);
}
while (val != val1);
return val;
}
void W5100Class::send_data_processing(SOCKET s, const uint8_t *data, uint16_t len)
{
// This is same as having no offset in a call to send_data_processing_offset
send_data_processing_offset(s, 0, data, len);
}
void W5100Class::send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len)
{
uint16_t ptr = readSnTX_WR(s);
ptr += data_offset;
uint16_t offset = ptr & SMASK;
uint16_t dstAddr = offset + SBASE[s];
if (offset + len > SSIZE)
{
// Wrap around circular buffer
uint16_t size = SSIZE - offset;
write(dstAddr, data, size);
write(SBASE[s], data + size, len - size);
}
else {
write(dstAddr, data, len);
}
ptr += len;
writeSnTX_WR(s, ptr);
}
void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek)
{
uint16_t ptr;
ptr = readSnRX_RD(s);
read_data(s, (uint8_t *)ptr, data, len);
if (!peek)
{
ptr += len;
writeSnRX_RD(s, ptr);
}
}
void W5100Class::read_data(SOCKET s, volatile uint8_t *src, volatile uint8_t *dst, uint16_t len)
{
uint16_t size;
uint16_t src_mask;
uint16_t src_ptr;
src_mask = (uint16_t)src & RMASK;
src_ptr = RBASE[s] + src_mask;
if( (src_mask + len) > RSIZE )
{
size = RSIZE - src_mask;
read(src_ptr, (uint8_t *)dst, size);
dst += size;
read(RBASE[s], (uint8_t *) dst, len - size);
}
else
read(src_ptr, (uint8_t *) dst, len);
}
uint8_t W5100Class::write(uint16_t _addr, uint8_t _data)
{
setSS();
#ifdef W5200
SPI.transfer(_addr >> 8);
SPI.transfer(_addr & 0xFF);
SPI.transfer(0x80);
SPI.transfer(0x01);
#else
SPI.transfer(0xF0);
SPI.transfer(_addr >> 8);
SPI.transfer(_addr & 0xFF);
#endif
SPI.transfer(_data);
resetSS();
return 1;
}
uint16_t W5100Class::write(uint16_t _addr, const uint8_t *_buf, uint16_t _len)
{
#ifdef W5200
setSS();
SPI.transfer(_addr >> 8);
SPI.transfer(_addr & 0xFF);
SPI.transfer((0x80 | ((_len & 0x7F00) >> 8)));
SPI.transfer(_len & 0x00FF);
for (uint16_t i=0; i<_len; i++)
{
SPI.transfer(_buf[i]);
}
resetSS();
#else
for (uint16_t i=0; i<_len; i++)
{
setSS();
SPI.transfer(0xF0);
SPI.transfer(_addr >> 8);
SPI.transfer(_addr & 0xFF);
_addr++;
SPI.transfer(_buf[i]);
resetSS();
}
#endif
return _len;
}
uint8_t W5100Class::read(uint16_t _addr)
{
setSS();
#ifdef W5200
SPI.transfer(_addr >> 8);
SPI.transfer(_addr & 0xFF);
SPI.transfer(0x00);
SPI.transfer(0x01);
#else
SPI.transfer(0x0F);
SPI.transfer(_addr >> 8);
SPI.transfer(_addr & 0xFF);
#endif
uint8_t _data = SPI.transfer(0);
resetSS();
return _data;
}
uint16_t W5100Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len)
{
#ifdef W5200
setSS();
SPI.transfer(_addr >> 8);
SPI.transfer(_addr & 0xFF);
SPI.transfer((0x00 | ((_len & 0x7F00) >> 8)));
SPI.transfer(_len & 0x00FF);
for (uint16_t i=0; i<_len; i++)
{
_buf[i] = SPI.transfer(0);
}
resetSS();
#else
for (uint16_t i=0; i<_len; i++)
{
setSS();
SPI.transfer(0x0F);
SPI.transfer(_addr >> 8);
SPI.transfer(_addr & 0xFF);
_addr++;
_buf[i] = SPI.transfer(0);
resetSS();
}
#endif
return _len;
}
void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd) {
// Send command to socket
writeSnCR(s, _cmd);
// Wait for command to complete
while (readSnCR(s))
;
}
/*
* Copyright (c) 2010 by Cristian Maglie <c.maglie@bug.st>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of either the GNU General Public License version 2
* or the GNU Lesser General Public License version 2.1, both as
* published by the Free Software Foundation.
*/
#ifndef W5100_H_INCLUDED
#define W5100_H_INCLUDED
#include <avr/pgmspace.h>
#include <SPI.h>
#define W5200
#ifdef W5200
#define MAX_SOCK_NUM 8
#else
#define MAX_SOCK_NUM 4
#endif
typedef uint8_t SOCKET;
#ifndef W5200
#define IDM_OR 0x8000
#define IDM_AR0 0x8001
#define IDM_AR1 0x8002
#define IDM_DR 0x8003
#endif
/*
class MR {
public:
static const uint8_t RST = 0x80;
static const uint8_t PB = 0x10;
static const uint8_t PPPOE = 0x08;
static const uint8_t LB = 0x04;
static const uint8_t AI = 0x02;
static const uint8_t IND = 0x01;
};
*/
/*
class IR {
public:
static const uint8_t CONFLICT = 0x80;
static const uint8_t UNREACH = 0x40;
static const uint8_t PPPoE = 0x20;
static const uint8_t SOCK0 = 0x01;
static const uint8_t SOCK1 = 0x02;
static const uint8_t SOCK2 = 0x04;
static const uint8_t SOCK3 = 0x08;
static inline uint8_t SOCK(SOCKET ch) { return (0x01 << ch); };
};
*/
class SnMR {
public:
static const uint8_t CLOSE = 0x00;
static const uint8_t TCP = 0x01;
static const uint8_t UDP = 0x02;
static const uint8_t IPRAW = 0x03;
static const uint8_t MACRAW = 0x04;
static const uint8_t PPPOE = 0x05;
static const uint8_t ND = 0x20;
static const uint8_t MULTI = 0x80;
};
enum SockCMD {
Sock_OPEN = 0x01,
Sock_LISTEN = 0x02,
Sock_CONNECT = 0x04,
Sock_DISCON = 0x08,
Sock_CLOSE = 0x10,
Sock_SEND = 0x20,
Sock_SEND_MAC = 0x21,
Sock_SEND_KEEP = 0x22,
Sock_RECV = 0x40
};
/*class SnCmd {
public:
static const uint8_t OPEN = 0x01;
static const uint8_t LISTEN = 0x02;
static const uint8_t CONNECT = 0x04;
static const uint8_t DISCON = 0x08;
static const uint8_t CLOSE = 0x10;
static const uint8_t SEND = 0x20;
static const uint8_t SEND_MAC = 0x21;
static const uint8_t SEND_KEEP = 0x22;
static const uint8_t RECV = 0x40;
};
*/
class SnIR {
public:
static const uint8_t SEND_OK = 0x10;
static const uint8_t TIMEOUT = 0x08;
static const uint8_t RECV = 0x04;
static const uint8_t DISCON = 0x02;
static const uint8_t CON = 0x01;
};
class SnSR {
public:
static const uint8_t CLOSED = 0x00;
static const uint8_t INIT = 0x13;
static const uint8_t LISTEN = 0x14;
static const uint8_t SYNSENT = 0x15;
static const uint8_t SYNRECV = 0x16;
static const uint8_t ESTABLISHED = 0x17;
static const uint8_t FIN_WAIT = 0x18;
static const uint8_t CLOSING = 0x1A;
static const uint8_t TIME_WAIT = 0x1B;
static const uint8_t CLOSE_WAIT = 0x1C;
static const uint8_t LAST_ACK = 0x1D;
static const uint8_t UDP = 0x22;
static const uint8_t IPRAW = 0x32;
static const uint8_t MACRAW = 0x42;
static const uint8_t PPPOE = 0x5F;
};
class IPPROTO {
public:
static const uint8_t IP = 0;
static const uint8_t ICMP = 1;
static const uint8_t IGMP = 2;
static const uint8_t GGP = 3;
static const uint8_t TCP = 6;
static const uint8_t PUP = 12;
static const uint8_t UDP = 17;
static const uint8_t IDP = 22;
static const uint8_t ND = 77;
static const uint8_t RAW = 255;
};
class W5100Class {
public:
void init();
/**
* @brief This function is being used for copy the data form Receive buffer of the chip to application buffer.
*
* It calculate the actual physical address where one has to read
* the data from Receive buffer. Here also take care of the condition while it exceed
* the Rx memory uper-bound of socket.
*/
void read_data(SOCKET s, volatile uint8_t * src, volatile uint8_t * dst, uint16_t len);
/**
* @brief This function is being called by send() and sendto() function also.
*
* This function read the Tx write pointer register and after copy the data in buffer update the Tx write pointer
* register. User should read upper byte first and lower byte later to get proper value.
*/
void send_data_processing(SOCKET s, const uint8_t *data, uint16_t len);
/**
* @brief A copy of send_data_processing that uses the provided ptr for the
* write offset. Only needed for the "streaming" UDP API, where
* a single UDP packet is built up over a number of calls to
* send_data_processing_ptr, because TX_WR doesn't seem to get updated
* correctly in those scenarios
* @param ptr value to use in place of TX_WR. If 0, then the value is read
* in from TX_WR
* @return New value for ptr, to be used in the next call
*/
// FIXME Update documentation
void send_data_processing_offset(SOCKET s, uint16_t data_offset, const uint8_t *data, uint16_t len);
/**
* @brief This function is being called by recv() also.
*
* This function read the Rx read pointer register
* and after copy the data from receive buffer update the Rx write pointer register.
* User should read upper byte first and lower byte later to get proper value.
*/
void recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek = 0);
inline void setGatewayIp(uint8_t *_addr);
inline void getGatewayIp(uint8_t *_addr);
inline void setSubnetMask(uint8_t *_addr);
inline void getSubnetMask(uint8_t *_addr);
inline void setMACAddress(uint8_t * addr);
inline void getMACAddress(uint8_t * addr);
inline void setIPAddress(uint8_t * addr);
inline void getIPAddress(uint8_t * addr);
inline void setRetransmissionTime(uint16_t timeout);
inline void setRetransmissionCount(uint8_t _retry);
void execCmdSn(SOCKET s, SockCMD _cmd);
uint16_t getTXFreeSize(SOCKET s);
uint16_t getRXReceivedSize(SOCKET s);
// W5100 Registers
// ---------------
private:
static uint8_t write(uint16_t _addr, uint8_t _data);
static uint16_t write(uint16_t addr, const uint8_t *buf, uint16_t len);
static uint8_t read(uint16_t addr);
static uint16_t read(uint16_t addr, uint8_t *buf, uint16_t len);
#define __GP_REGISTER8(name, address) \
static inline void write##name(uint8_t _data) { \
write(address, _data); \
} \
static inline uint8_t read##name() { \
return read(address); \
}
#define __GP_REGISTER16(name, address) \
static void write##name(uint16_t _data) { \
write(address, _data >> 8); \
write(address+1, _data & 0xFF); \
} \
static uint16_t read##name() { \
uint16_t res = read(address); \
res = (res << 8) + read(address + 1); \
return res; \
}
#define __GP_REGISTER_N(name, address, size) \
static uint16_t write##name(uint8_t *_buff) { \
return write(address, _buff, size); \
} \
static uint16_t read##name(uint8_t *_buff) { \
return read(address, _buff, size); \
}
public:
__GP_REGISTER8 (MR, 0x0000); // Mode
__GP_REGISTER_N(GAR, 0x0001, 4); // Gateway IP address
__GP_REGISTER_N(SUBR, 0x0005, 4); // Subnet mask address
__GP_REGISTER_N(SHAR, 0x0009, 6); // Source MAC address
__GP_REGISTER_N(SIPR, 0x000F, 4); // Source IP address
__GP_REGISTER8 (IR, 0x0015); // Interrupt
__GP_REGISTER8 (IMR, 0x0016); // Interrupt Mask
__GP_REGISTER16(RTR, 0x0017); // Timeout address
__GP_REGISTER8 (RCR, 0x0019); // Retry count
#ifndef W5200
__GP_REGISTER8 (RMSR, 0x001A); // Receive memory size
__GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size
#endif
__GP_REGISTER8 (PATR, 0x001C); // Authentication type address in PPPoE mode
__GP_REGISTER8 (PTIMER, 0x0028); // PPP LCP Request Timer
__GP_REGISTER8 (PMAGIC, 0x0029); // PPP LCP Magic Number
#ifndef W5200
__GP_REGISTER_N(UIPR, 0x002A, 4); // Unreachable IP address in UDP mode
__GP_REGISTER16(UPORT, 0x002E); // Unreachable Port address in UDP mode
#endif
#undef __GP_REGISTER8
#undef __GP_REGISTER16
#undef __GP_REGISTER_N
// W5100 Socket registers
// ----------------------
private:
static inline uint8_t readSn(SOCKET _s, uint16_t _addr);
static inline uint8_t writeSn(SOCKET _s, uint16_t _addr, uint8_t _data);
static inline uint16_t readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len);
static inline uint16_t writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t len);
#ifdef W5200
static const uint16_t CH_BASE = 0x4000;
#else
static const uint16_t CH_BASE = 0x0400;
#endif
static const uint16_t CH_SIZE = 0x0100;
#define __SOCKET_REGISTER8(name, address) \
static inline void write##name(SOCKET _s, uint8_t _data) { \
writeSn(_s, address, _data); \
} \
static inline uint8_t read##name(SOCKET _s) { \
return readSn(_s, address); \
}
#define __SOCKET_REGISTER16(name, address) \
static void write##name(SOCKET _s, uint16_t _data) { \
writeSn(_s, address, _data >> 8); \
writeSn(_s, address+1, _data & 0xFF); \
} \
static uint16_t read##name(SOCKET _s) { \
uint16_t res = readSn(_s, address); \
res = (res << 8) + readSn(_s, address + 1); \
return res; \
}
#define __SOCKET_REGISTER_N(name, address, size) \
static uint16_t write##name(SOCKET _s, uint8_t *_buff) { \
return writeSn(_s, address, _buff, size); \
} \
static uint16_t read##name(SOCKET _s, uint8_t *_buff) { \
return readSn(_s, address, _buff, size); \
}
public:
__SOCKET_REGISTER8(SnMR, 0x0000) // Mode
__SOCKET_REGISTER8(SnCR, 0x0001) // Command
__SOCKET_REGISTER8(SnIR, 0x0002) // Interrupt
__SOCKET_REGISTER8(SnSR, 0x0003) // Status
__SOCKET_REGISTER16(SnPORT, 0x0004) // Source Port
__SOCKET_REGISTER_N(SnDHAR, 0x0006, 6) // Destination Hardw Addr
__SOCKET_REGISTER_N(SnDIPR, 0x000C, 4) // Destination IP Addr
__SOCKET_REGISTER16(SnDPORT, 0x0010) // Destination Port
__SOCKET_REGISTER16(SnMSSR, 0x0012) // Max Segment Size
__SOCKET_REGISTER8(SnPROTO, 0x0014) // Protocol in IP RAW Mode
__SOCKET_REGISTER8(SnTOS, 0x0015) // IP TOS
__SOCKET_REGISTER8(SnTTL, 0x0016) // IP TTL
__SOCKET_REGISTER16(SnTX_FSR, 0x0020) // TX Free Size
__SOCKET_REGISTER16(SnTX_RD, 0x0022) // TX Read Pointer
__SOCKET_REGISTER16(SnTX_WR, 0x0024) // TX Write Pointer
__SOCKET_REGISTER16(SnRX_RSR, 0x0026) // RX Free Size
__SOCKET_REGISTER16(SnRX_RD, 0x0028) // RX Read Pointer
__SOCKET_REGISTER16(SnRX_WR, 0x002A) // RX Write Pointer (supported?)
#undef __SOCKET_REGISTER8
#undef __SOCKET_REGISTER16
#undef __SOCKET_REGISTER_N
private:
static const uint8_t RST = 7; // Reset BIT
#ifdef W5200
static const int SOCKETS = 8;
#else
static const int SOCKETS = 4;
#endif
static const uint16_t SMASK = 0x07FF; // Tx buffer MASK
static const uint16_t RMASK = 0x07FF; // Rx buffer MASK
public:
static const uint16_t SSIZE = 2048; // Max Tx buffer size
private:
static const uint16_t RSIZE = 2048; // Max Rx buffer size
uint16_t SBASE[SOCKETS]; // Tx buffer base address
uint16_t RBASE[SOCKETS]; // Rx buffer base address
private:
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
inline static void initSS() { DDRB |= _BV(4); };
inline static void setSS() { PORTB &= ~_BV(4); };
inline static void resetSS() { PORTB |= _BV(4); };
#elif defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB162__)
inline static void initSS() { DDRB |= _BV(0); };
inline static void setSS() { PORTB &= ~_BV(0); };
inline static void resetSS() { PORTB |= _BV(0); };
#else
inline static void initSS() { DDRB |= _BV(2); };
inline static void setSS() { PORTB &= ~_BV(2); };
inline static void resetSS() { PORTB |= _BV(2); };
#endif
};
extern W5100Class W5100;
uint8_t W5100Class::readSn(SOCKET _s, uint16_t _addr) {
return read(CH_BASE + _s * CH_SIZE + _addr);
}
uint8_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t _data) {
return write(CH_BASE + _s * CH_SIZE + _addr, _data);
}
uint16_t W5100Class::readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) {
return read(CH_BASE + _s * CH_SIZE + _addr, _buf, _len);
}
uint16_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) {
return write(CH_BASE + _s * CH_SIZE + _addr, _buf, _len);
}
void W5100Class::getGatewayIp(uint8_t *_addr) {
readGAR(_addr);
}
void W5100Class::setGatewayIp(uint8_t *_addr) {
writeGAR(_addr);
}
void W5100Class::getSubnetMask(uint8_t *_addr) {
readSUBR(_addr);
}
void W5100Class::setSubnetMask(uint8_t *_addr) {
writeSUBR(_addr);
}
void W5100Class::getMACAddress(uint8_t *_addr) {
readSHAR(_addr);
}
void W5100Class::setMACAddress(uint8_t *_addr) {
writeSHAR(_addr);
}
void W5100Class::getIPAddress(uint8_t *_addr) {
readSIPR(_addr);
}
void W5100Class::setIPAddress(uint8_t *_addr) {
writeSIPR(_addr);
}
void W5100Class::setRetransmissionTime(uint16_t _timeout) {
writeRTR(_timeout);
}
void W5100Class::setRetransmissionCount(uint8_t _retry) {
writeRCR(_retry);
}
#endif