From 3cab0e574ee1c06c1c86a409bd452c3978f7e676 Mon Sep 17 00:00:00 2001 From: Federico Vanzati Date: Fri, 19 Sep 2014 10:56:19 +0200 Subject: [PATCH 01/15] Ethernet: runtime autodetection of chipset W5100/W5200/W5500 Based on code from: https://github.com/jbkim/Differentiate-WIznet-Chip --- libraries/Ethernet/src/utility/w5100.cpp | 43 ++++++++++++++++++++++++ libraries/Ethernet/src/utility/w5100.h | 2 ++ 2 files changed, 45 insertions(+) diff --git a/libraries/Ethernet/src/utility/w5100.cpp b/libraries/Ethernet/src/utility/w5100.cpp index f616d0634ea..6629e092f6d 100644 --- a/libraries/Ethernet/src/utility/w5100.cpp +++ b/libraries/Ethernet/src/utility/w5100.cpp @@ -35,6 +35,49 @@ void W5100Class::init(void) SPI.setClockDivider(ETHERNET_SHIELD_SPI_CS, 21); SPI.setDataMode(ETHERNET_SHIELD_SPI_CS, SPI_MODE0); #endif + + /* + * Runtime detection of Wiznet Chip. + * Based on code from: https://github.com/jbkim/Differentiate-WIznet-Chip + */ + uint8_t testW5200[] = { 0x00, 0x1F, 0x00, 0x01, 0x00 }; + uint8_t testW5500[] = { 0x00, 0x39, 0x00, 0x00 }; + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); +#if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) + // Check for W5200 + setSS(); + SPI.transfer(testW5200, 5); + resetSS(); + if (testW5200[4] == 0x03) { + chipset = 2; + } else { + // Check for W5500 + setSS(); + SPI.transfer(testW5500, 4); + resetSS(); + if (testW5500[3] == 0x04) { + chipset = 5; + } else { + chipset = 1; + } + } +#else + // Check for W5200 + SPI.transfer(ETHERNET_SHIELD_SPI_CS, testW5200, 5); + if (testW5200[4] == 0x03) { + chipset = 2; + } else { + // Check for W5500 + SPI.transfer(ETHERNET_SHIELD_SPI_CS, testW5500, 4); + if (testW5500[3] == 0x04) { + chipset = 5; + } else { + chipset = 1; + } + } +#endif + SPI.endTransaction(); + SPI.beginTransaction(SPI_ETHERNET_SETTINGS); writeMR(1< Date: Fri, 19 Sep 2014 12:17:31 +0200 Subject: [PATCH 02/15] Ethernet: added support for W5500 - Chipset is autodetected during init(). - Still missing support for W5200. - Some more optimization may be made on read*/write* functions by splitting into specific read{W5100|W5200|W5500} function and moving the chipset selection to the caller. --- libraries/Ethernet/src/utility/w5100.cpp | 277 ++++++++++++++++------- libraries/Ethernet/src/utility/w5100.h | 153 ++++++++----- 2 files changed, 292 insertions(+), 138 deletions(-) diff --git a/libraries/Ethernet/src/utility/w5100.cpp b/libraries/Ethernet/src/utility/w5100.cpp index 6629e092f6d..e42ced5740c 100644 --- a/libraries/Ethernet/src/utility/w5100.cpp +++ b/libraries/Ethernet/src/utility/w5100.cpp @@ -15,6 +15,9 @@ // W5100 controller instance W5100Class W5100; +uint8_t W5100Class::chipset = 0; +uint8_t W5100Class::sockets = 4; + #define TX_RX_MAX_BUF_SIZE 2048 #define TX_BUF 0x1100 #define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE) @@ -78,15 +81,28 @@ void W5100Class::init(void) #endif SPI.endTransaction(); - SPI.beginTransaction(SPI_ETHERNET_SETTINGS); - writeMR(1< 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); + if (chipset == 1) { + 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, 0x00, data, size); + write(SBASE[s], 0x00, data + size, len - size); + } else { + write(dstAddr, 0x00, data, len); + } + } else if (chipset == 2) { + // XXX: TODO + } else { + write(ptr, (s<<5) + 0x14, data, len); } ptr += len; @@ -146,8 +167,7 @@ void W5100Class::send_data_processing_offset(SOCKET s, uint16_t data_offset, con void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek) { - uint16_t ptr; - ptr = readSnRX_RD(s); + uint16_t ptr = readSnRX_RD(s); read_data(s, ptr, data, len); if (!peek) { @@ -158,104 +178,200 @@ void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uin void W5100Class::read_data(SOCKET s, volatile uint16_t src, volatile uint8_t *dst, uint16_t len) { - uint16_t size; - uint16_t src_mask; - uint16_t src_ptr; - - src_mask = 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); + if (chipset == 1) { + uint16_t src_mask = src & RMASK; + uint16_t src_ptr = RBASE[s] + src_mask; + if ((src_mask + len) > RSIZE) { + uint16_t size = RSIZE - src_mask; + read(src_ptr, 0x00, (uint8_t *)dst, size); + dst += size; + read(RBASE[s], 0x00, (uint8_t *) dst, len - size); + } else { + read(src_ptr, 0x00, (uint8_t *) dst, len); + } + } else if (chipset == 2) { + // XXX: Missing 5200 + } else { + read((uint16_t)src , (s<<5) + 0x18, (uint8_t *)dst, len); + } } -uint8_t W5100Class::write(uint16_t _addr, uint8_t _data) +uint8_t W5100Class::write(uint16_t _addr, uint8_t _cb, uint8_t _data) { #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) - setSS(); - SPI.transfer(0xF0); - SPI.transfer(_addr >> 8); - SPI.transfer(_addr & 0xFF); - SPI.transfer(_data); + setSS(); + if (chipset == 1) { + SPI.transfer(0xF0); + SPI.transfer(_addr >> 8); + SPI.transfer(_addr & 0xFF); + SPI.transfer(_data); + } else if (chipset == 2) { + // XXX: Missing 5200 + } else { + SPI.transfer(_addr >> 8); + SPI.transfer(_addr & 0xFF); + SPI.transfer(_cb); + SPI.transfer(_data); + } resetSS(); #else - SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0xF0, SPI_CONTINUE); - SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); - SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); - SPI.transfer(ETHERNET_SHIELD_SPI_CS, _data); + if (chipset == 1) { + SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0xF0, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _data); + } else if (chipset == 2) { + // XXX: Missing 5200 + } else { + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _cb, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _data); + } #endif return 1; } -uint16_t W5100Class::write(uint16_t _addr, const uint8_t *_buf, uint16_t _len) +uint16_t W5100Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uint16_t _len) { - for (uint16_t i=0; i<_len; i++) - { #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) - setSS(); - SPI.transfer(0xF0); + if (chipset == 1) { + 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(); + } + } else if (chipset == 2) { + // XXX: Missing 5200 + } else { + setSS(); SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); - _addr++; - SPI.transfer(_buf[i]); + SPI.transfer(_cb); + for (uint16_t i=0; i<_len; i++){ + SPI.transfer(_buf[i]); + } resetSS(); + } #else - SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0xF0, SPI_CONTINUE); + if (chipset == 1) { + for (uint16_t i=0; i<_len; i++) + { + SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0xF0, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _buf[i]); + _addr++; + } + } else if (chipset == 2) { + // XXX: Missing 5200 + } else { + uint16_t i; SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _cb, SPI_CONTINUE); + for (i=0; i<_len-1; i++){ + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _buf[i], SPI_CONTINUE); + } SPI.transfer(ETHERNET_SHIELD_SPI_CS, _buf[i]); - _addr++; -#endif } +#endif return _len; } -uint8_t W5100Class::read(uint16_t _addr) +uint8_t W5100Class::read(uint16_t _addr, uint8_t _cb) { + uint8_t res; #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) - setSS(); - SPI.transfer(0x0F); - SPI.transfer(_addr >> 8); - SPI.transfer(_addr & 0xFF); - uint8_t _data = SPI.transfer(0); + setSS(); + if (chipset == 1) { + SPI.transfer(0x0F); + SPI.transfer(_addr >> 8); + SPI.transfer(_addr & 0xFF); + res = SPI.transfer(0); + } else if (chipset == 2) { + // XXX: Missing 5200 + } else { + SPI.transfer(_addr >> 8); + SPI.transfer(_addr & 0xFF); + SPI.transfer(_cb); + res = SPI.transfer(0); + } resetSS(); #else - SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x0F, SPI_CONTINUE); - SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); - SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); - uint8_t _data = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0); + if (chipset == 1) { + SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x0F, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); + res = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0); + } else if (chipset == 2) { + // XXX: Missing 5200 + } else { + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _cb, SPI_CONTINUE); + uint8_t _data = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0); + } #endif - return _data; + return res; } -uint16_t W5100Class::read(uint16_t _addr, uint8_t *_buf, uint16_t _len) +uint16_t W5100Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _len) { - for (uint16_t i=0; i<_len; i++) - { #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) + if (chipset == 1) { + 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(); + } + } else if (chipset == 2) { + // XXX: Missing 5200 + } else { setSS(); - SPI.transfer(0x0F); SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); - _addr++; - _buf[i] = SPI.transfer(0); + SPI.transfer(_cb); + for (uint16_t i=0; i<_len; i++){ + _buf[i] = SPI.transfer(0); + } resetSS(); + } #else - SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x0F, SPI_CONTINUE); + if (chipset == 1) { + for (uint16_t i=0; i<_len; i++) + { + SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x0F, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); + _buf[i] = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0); + _addr++; + } + } else if (chipset == 2) { + // XXX: Missing 5200 + } else { + uint16_t i; SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); - _buf[i] = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0); - _addr++; -#endif + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _cb, SPI_CONTINUE); + for (i=0; i<_len-1; i++){ + _buf[i] = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0, SPI_CONTINUE); + } + _buf[_len-1] = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0); } +#endif + return _len; } @@ -266,3 +382,4 @@ void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd) { while (readSnCR(s)) ; } + diff --git a/libraries/Ethernet/src/utility/w5100.h b/libraries/Ethernet/src/utility/w5100.h index 3a24bad6df4..5ea8557b1ce 100644 --- a/libraries/Ethernet/src/utility/w5100.h +++ b/libraries/Ethernet/src/utility/w5100.h @@ -14,8 +14,6 @@ #define ETHERNET_SHIELD_SPI_CS 10 -#define MAX_SOCK_NUM 4 - typedef uint8_t SOCKET; #define IDM_OR 0x8000 @@ -192,58 +190,64 @@ class W5100Class { private: static uint8_t chipset; + static uint8_t sockets; // 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); + static uint8_t write(uint16_t _addr, uint8_t _cb, uint8_t _data); + static uint16_t write(uint16_t addr, uint8_t _cb, const uint8_t *buf, uint16_t len); + static uint8_t read(uint16_t addr, uint8_t _cb); + static uint16_t read(uint16_t addr, uint8_t _cb, uint8_t *buf, uint16_t len); #define __GP_REGISTER8(name, address) \ static inline void write##name(uint8_t _data) { \ - write(address, _data); \ + write(address, 0x04, _data); \ } \ static inline uint8_t read##name() { \ - return read(address); \ + return read(address, 0x00); \ } #define __GP_REGISTER16(name, address) \ static void write##name(uint16_t _data) { \ - write(address, _data >> 8); \ - write(address+1, _data & 0xFF); \ + write(address, 0x04, _data >> 8); \ + write(address+1, 0x04, _data & 0xFF); \ } \ static uint16_t read##name() { \ - uint16_t res = read(address); \ - res = (res << 8) + read(address + 1); \ + uint16_t res = read(address, 0x00); \ + res = (res << 8) + read(address + 1, 0x00); \ return res; \ } #define __GP_REGISTER_N(name, address, size) \ static uint16_t write##name(uint8_t *_buff) { \ - return write(address, _buff, size); \ + return write(address, 0x04, _buff, size); \ } \ static uint16_t read##name(uint8_t *_buff) { \ - return read(address, _buff, size); \ + return read(address, 0x00, _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 - __GP_REGISTER8 (RMSR, 0x001A); // Receive memory size - __GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size - __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 - __GP_REGISTER_N(UIPR, 0x002A, 4); // Unreachable IP address in UDP mode - __GP_REGISTER16(UPORT, 0x002E); // Unreachable Port address in UDP mode - + __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_W5100, 0x0017); // Timeout address + __GP_REGISTER16(RTR_W5500, 0x0019); // Timeout address + __GP_REGISTER8 (RCR_W5100, 0x0019); // Retry count + __GP_REGISTER8 (RCR_W5500, 0x001B); // Retry count + __GP_REGISTER8 (RMSR, 0x001A); // Receive memory size + __GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size + __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 + __GP_REGISTER_N(UIPR_W5100, 0x002A, 4); // Unreachable IP address in UDP mode + __GP_REGISTER_N(UIPR_W5500, 0x0028, 4); // Unreachable IP address in UDP mode + __GP_REGISTER16(UPORT_W5100, 0x002E); // Unreachable Port address in UDP mode + __GP_REGISTER16(UPORT_W5500, 0x002C); // Unreachable Port address in UDP mode + __GP_REGISTER8 (PHYCFGR_W5500, 0x002E); // PHY Configuration register, default value: 0b 1011 1xxx + #undef __GP_REGISTER8 #undef __GP_REGISTER16 #undef __GP_REGISTER_N @@ -288,24 +292,26 @@ class W5100Class { } 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?) + __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_REGISTER8(SnRXBUF_SIZE, 0x001E) // RX Buffer Size + __SOCKET_REGISTER8(SnTXBUF_SIZE, 0x001F) // TX Buffer Size + __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 @@ -315,15 +321,14 @@ class W5100Class { private: static const uint8_t RST = 7; // Reset BIT - static const int SOCKETS = 4; 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 + uint16_t SBASE[4]; // Tx buffer base address + uint16_t RBASE[4]; // Rx buffer base address private: #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) @@ -370,19 +375,39 @@ class W5100Class { extern W5100Class W5100; uint8_t W5100Class::readSn(SOCKET _s, uint16_t _addr) { - return read(CH_BASE + _s * CH_SIZE + _addr); + if (chipset == 1) + return read(CH_BASE + _s * CH_SIZE + _addr, 0x00); + if (chipset == 2) + return 0; // XXX: TODO + if (chipset == 5) + return read(_addr, (_s<<5) + 0x08); } uint8_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t _data) { - return write(CH_BASE + _s * CH_SIZE + _addr, _data); + if (chipset == 1) + return write(CH_BASE + _s * CH_SIZE + _addr, 0x00, _data); + if (chipset == 2) + return 0; // XXX: TODO + if (chipset == 5) + return write(_addr, (_s<<5) + 0x0C, _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); + if (chipset == 1) + return read(CH_BASE + _s * CH_SIZE + _addr, 0x00, _buf, _len); + if (chipset == 2) + return 0; // XXX: TODO + if (chipset == 5) + return read(_addr, (_s<<5) + 0x08, _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); + if (chipset == 1) + return write(CH_BASE + _s * CH_SIZE + _addr, 0x00, _buf, _len); + if (chipset == 2) + return 0; // XXX: TODO + if (chipset == 5) + return write(_addr, (_s<<5) + 0x0C, _buf, _len); } void W5100Class::getGatewayIp(uint8_t *_addr) { @@ -418,11 +443,23 @@ void W5100Class::setIPAddress(uint8_t *_addr) { } void W5100Class::setRetransmissionTime(uint16_t _timeout) { - writeRTR(_timeout); + if (chipset == 1) { + writeRTR_W5100(_timeout); + } else if (chipset == 2) { + // XXX: TODO + } else { + writeRTR_W5500(_timeout); + } } void W5100Class::setRetransmissionCount(uint8_t _retry) { - writeRCR(_retry); + if (chipset == 1) { + writeRCR_W5100(_retry); + } else if (chipset == 2) { + // XXX: TODO + } else { + writeRCR_W5500(_retry); + } } #endif From 5365b9d1049422362f36f940a048ddba0bef9b85 Mon Sep 17 00:00:00 2001 From: Federico Vanzati Date: Fri, 19 Sep 2014 13:46:47 +0200 Subject: [PATCH 03/15] Ethernet: renamed W5100Class to W5x00Class Instance name is left to W5100 to allow compatibility for libraries that builds on top of Ethernet library. --- libraries/Ethernet/src/utility/w5100.cpp | 32 +++++++++---------- libraries/Ethernet/src/utility/w5100.h | 40 ++++++++++++------------ 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/libraries/Ethernet/src/utility/w5100.cpp b/libraries/Ethernet/src/utility/w5100.cpp index e42ced5740c..ddfe818eb94 100644 --- a/libraries/Ethernet/src/utility/w5100.cpp +++ b/libraries/Ethernet/src/utility/w5100.cpp @@ -12,11 +12,11 @@ #include "w5100.h" -// W5100 controller instance -W5100Class W5100; +// W5x00 controller instance +W5x00Class W5100; -uint8_t W5100Class::chipset = 0; -uint8_t W5100Class::sockets = 4; +uint8_t W5x00Class::chipset = 0; +uint8_t W5x00Class::sockets = 4; #define TX_RX_MAX_BUF_SIZE 2048 #define TX_BUF 0x1100 @@ -25,7 +25,7 @@ uint8_t W5100Class::sockets = 4; #define TXBUF_BASE 0x4000 #define RXBUF_BASE 0x6000 -void W5100Class::init(void) +void W5x00Class::init(void) { delay(300); @@ -106,7 +106,7 @@ void W5100Class::init(void) } } -uint16_t W5100Class::getTXFreeSize(SOCKET s) +uint16_t W5x00Class::getTXFreeSize(SOCKET s) { uint16_t val=0, val1=0; do { @@ -118,7 +118,7 @@ uint16_t W5100Class::getTXFreeSize(SOCKET s) return val; } -uint16_t W5100Class::getRXReceivedSize(SOCKET s) +uint16_t W5x00Class::getRXReceivedSize(SOCKET s) { uint16_t val=0,val1=0; do { @@ -131,13 +131,13 @@ uint16_t W5100Class::getRXReceivedSize(SOCKET s) } -void W5100Class::send_data_processing(SOCKET s, const uint8_t *data, uint16_t len) +void W5x00Class::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) +void W5x00Class::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; @@ -165,7 +165,7 @@ void W5100Class::send_data_processing_offset(SOCKET s, uint16_t data_offset, con } -void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek) +void W5x00Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek) { uint16_t ptr = readSnRX_RD(s); read_data(s, ptr, data, len); @@ -176,7 +176,7 @@ void W5100Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uin } } -void W5100Class::read_data(SOCKET s, volatile uint16_t src, volatile uint8_t *dst, uint16_t len) +void W5x00Class::read_data(SOCKET s, volatile uint16_t src, volatile uint8_t *dst, uint16_t len) { if (chipset == 1) { uint16_t src_mask = src & RMASK; @@ -197,7 +197,7 @@ void W5100Class::read_data(SOCKET s, volatile uint16_t src, volatile uint8_t *ds } -uint8_t W5100Class::write(uint16_t _addr, uint8_t _cb, uint8_t _data) +uint8_t W5x00Class::write(uint16_t _addr, uint8_t _cb, uint8_t _data) { #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) setSS(); @@ -233,7 +233,7 @@ uint8_t W5100Class::write(uint16_t _addr, uint8_t _cb, uint8_t _data) return 1; } -uint16_t W5100Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uint16_t _len) +uint16_t W5x00Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uint16_t _len) { #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) if (chipset == 1) { @@ -285,7 +285,7 @@ uint16_t W5100Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uin return _len; } -uint8_t W5100Class::read(uint16_t _addr, uint8_t _cb) +uint8_t W5x00Class::read(uint16_t _addr, uint8_t _cb) { uint8_t res; #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) @@ -322,7 +322,7 @@ uint8_t W5100Class::read(uint16_t _addr, uint8_t _cb) return res; } -uint16_t W5100Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _len) +uint16_t W5x00Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _len) { #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) if (chipset == 1) { @@ -375,7 +375,7 @@ uint16_t W5100Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _ return _len; } -void W5100Class::execCmdSn(SOCKET s, SockCMD _cmd) { +void W5x00Class::execCmdSn(SOCKET s, SockCMD _cmd) { // Send command to socket writeSnCR(s, _cmd); // Wait for command to complete diff --git a/libraries/Ethernet/src/utility/w5100.h b/libraries/Ethernet/src/utility/w5100.h index 5ea8557b1ce..0a36ca94607 100644 --- a/libraries/Ethernet/src/utility/w5100.h +++ b/libraries/Ethernet/src/utility/w5100.h @@ -7,8 +7,8 @@ * published by the Free Software Foundation. */ -#ifndef W5100_H_INCLUDED -#define W5100_H_INCLUDED +#ifndef W5x00_H_INCLUDED +#define W5x00_H_INCLUDED #include @@ -125,7 +125,7 @@ class IPPROTO { static const uint8_t RAW = 255; }; -class W5100Class { +class W5x00Class { public: void init(); @@ -192,7 +192,7 @@ class W5100Class { static uint8_t chipset; static uint8_t sockets; - // W5100 Registers + // W5x00 Registers // --------------- private: static uint8_t write(uint16_t _addr, uint8_t _cb, uint8_t _data); @@ -252,7 +252,7 @@ class W5100Class { #undef __GP_REGISTER16 #undef __GP_REGISTER_N - // W5100 Socket registers + // W5x00 Socket registers // ---------------------- private: static inline uint8_t readSn(SOCKET _s, uint16_t _addr); @@ -372,9 +372,9 @@ class W5100Class { #endif }; -extern W5100Class W5100; +extern W5x00Class W5100; -uint8_t W5100Class::readSn(SOCKET _s, uint16_t _addr) { +uint8_t W5x00Class::readSn(SOCKET _s, uint16_t _addr) { if (chipset == 1) return read(CH_BASE + _s * CH_SIZE + _addr, 0x00); if (chipset == 2) @@ -383,7 +383,7 @@ uint8_t W5100Class::readSn(SOCKET _s, uint16_t _addr) { return read(_addr, (_s<<5) + 0x08); } -uint8_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t _data) { +uint8_t W5x00Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t _data) { if (chipset == 1) return write(CH_BASE + _s * CH_SIZE + _addr, 0x00, _data); if (chipset == 2) @@ -392,7 +392,7 @@ uint8_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t _data) { return write(_addr, (_s<<5) + 0x0C, _data); } -uint16_t W5100Class::readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) { +uint16_t W5x00Class::readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) { if (chipset == 1) return read(CH_BASE + _s * CH_SIZE + _addr, 0x00, _buf, _len); if (chipset == 2) @@ -401,7 +401,7 @@ uint16_t W5100Class::readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _ return read(_addr, (_s<<5) + 0x08, _buf, _len); } -uint16_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) { +uint16_t W5x00Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) { if (chipset == 1) return write(CH_BASE + _s * CH_SIZE + _addr, 0x00, _buf, _len); if (chipset == 2) @@ -410,39 +410,39 @@ uint16_t W5100Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t return write(_addr, (_s<<5) + 0x0C, _buf, _len); } -void W5100Class::getGatewayIp(uint8_t *_addr) { +void W5x00Class::getGatewayIp(uint8_t *_addr) { readGAR(_addr); } -void W5100Class::setGatewayIp(uint8_t *_addr) { +void W5x00Class::setGatewayIp(uint8_t *_addr) { writeGAR(_addr); } -void W5100Class::getSubnetMask(uint8_t *_addr) { +void W5x00Class::getSubnetMask(uint8_t *_addr) { readSUBR(_addr); } -void W5100Class::setSubnetMask(uint8_t *_addr) { +void W5x00Class::setSubnetMask(uint8_t *_addr) { writeSUBR(_addr); } -void W5100Class::getMACAddress(uint8_t *_addr) { +void W5x00Class::getMACAddress(uint8_t *_addr) { readSHAR(_addr); } -void W5100Class::setMACAddress(uint8_t *_addr) { +void W5x00Class::setMACAddress(uint8_t *_addr) { writeSHAR(_addr); } -void W5100Class::getIPAddress(uint8_t *_addr) { +void W5x00Class::getIPAddress(uint8_t *_addr) { readSIPR(_addr); } -void W5100Class::setIPAddress(uint8_t *_addr) { +void W5x00Class::setIPAddress(uint8_t *_addr) { writeSIPR(_addr); } -void W5100Class::setRetransmissionTime(uint16_t _timeout) { +void W5x00Class::setRetransmissionTime(uint16_t _timeout) { if (chipset == 1) { writeRTR_W5100(_timeout); } else if (chipset == 2) { @@ -452,7 +452,7 @@ void W5100Class::setRetransmissionTime(uint16_t _timeout) { } } -void W5100Class::setRetransmissionCount(uint8_t _retry) { +void W5x00Class::setRetransmissionCount(uint8_t _retry) { if (chipset == 1) { writeRCR_W5100(_retry); } else if (chipset == 2) { From 0998c26f2ce2053a7b9e3405a512475b55d0133e Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Sep 2014 16:58:05 +0200 Subject: [PATCH 04/15] Ethernet: added support for W5200 --- libraries/Ethernet/src/utility/w5100.cpp | 113 +++++++++++++++++------ libraries/Ethernet/src/utility/w5100.h | 84 +++++++---------- 2 files changed, 121 insertions(+), 76 deletions(-) diff --git a/libraries/Ethernet/src/utility/w5100.cpp b/libraries/Ethernet/src/utility/w5100.cpp index ddfe818eb94..abf0729e3e8 100644 --- a/libraries/Ethernet/src/utility/w5100.cpp +++ b/libraries/Ethernet/src/utility/w5100.cpp @@ -22,9 +22,6 @@ uint8_t W5x00Class::sockets = 4; #define TX_BUF 0x1100 #define RX_BUF (TX_BUF + TX_RX_MAX_BUF_SIZE) -#define TXBUF_BASE 0x4000 -#define RXBUF_BASE 0x6000 - void W5x00Class::init(void) { delay(300); @@ -90,19 +87,37 @@ void W5x00Class::init(void) writeRMSR(0x55); SPI.endTransaction(); - for (int i=0; i SSIZE) @@ -154,8 +168,6 @@ void W5x00Class::send_data_processing_offset(SOCKET s, uint16_t data_offset, con } else { write(dstAddr, 0x00, data, len); } - } else if (chipset == 2) { - // XXX: TODO } else { write(ptr, (s<<5) + 0x14, data, len); } @@ -164,7 +176,6 @@ void W5x00Class::send_data_processing_offset(SOCKET s, uint16_t data_offset, con writeSnTX_WR(s, ptr); } - void W5x00Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uint8_t peek) { uint16_t ptr = readSnRX_RD(s); @@ -178,7 +189,7 @@ void W5x00Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uin void W5x00Class::read_data(SOCKET s, volatile uint16_t src, volatile uint8_t *dst, uint16_t len) { - if (chipset == 1) { + if (chipset != 5) { uint16_t src_mask = src & RMASK; uint16_t src_ptr = RBASE[s] + src_mask; if ((src_mask + len) > RSIZE) { @@ -189,8 +200,6 @@ void W5x00Class::read_data(SOCKET s, volatile uint16_t src, volatile uint8_t *ds } else { read(src_ptr, 0x00, (uint8_t *) dst, len); } - } else if (chipset == 2) { - // XXX: Missing 5200 } else { read((uint16_t)src , (s<<5) + 0x18, (uint8_t *)dst, len); } @@ -207,7 +216,11 @@ uint8_t W5x00Class::write(uint16_t _addr, uint8_t _cb, uint8_t _data) SPI.transfer(_addr & 0xFF); SPI.transfer(_data); } else if (chipset == 2) { - // XXX: Missing 5200 + SPI.transfer(_addr >> 8); + SPI.transfer(_addr & 0xFF); + SPI.transfer(0x80); + SPI.transfer(0x01); + SPI.transfer(_data); } else { SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); @@ -222,7 +235,11 @@ uint8_t W5x00Class::write(uint16_t _addr, uint8_t _cb, uint8_t _data) SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _data); } else if (chipset == 2) { - // XXX: Missing 5200 + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x80, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x01, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _data); } else { SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); @@ -248,20 +265,31 @@ uint16_t W5x00Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uin resetSS(); } } else if (chipset == 2) { - // XXX: Missing 5200 + if (_len == 0) + return 0; + setSS(); + SPI.transfer(_addr >> 8); + SPI.transfer(_addr & 0xFF); + SPI.transfer(0x80 | ((_len & 0x7F00) >> 8)); + SPI.transfer(_len & 0xFF); + for (uint16_t i=0; i<_len; i++) { + SPI.transfer(_buf[i]); + } + resetSS(); } else { setSS(); SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); SPI.transfer(_cb); - for (uint16_t i=0; i<_len; i++){ + for (uint16_t i=0; i<_len; i++) { SPI.transfer(_buf[i]); } resetSS(); } #else + uint16_t i; if (chipset == 1) { - for (uint16_t i=0; i<_len; i++) + for (i=0; i<_len; i++) { SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0xF0, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); @@ -270,13 +298,21 @@ uint16_t W5x00Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uin _addr++; } } else if (chipset == 2) { - // XXX: Missing 5200 + if (_len == 0) + return 0; + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x80 | ((_len & 0x7F00) >> 8), SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _len & 0xFF, SPI_CONTINUE); + for (i=0; i<_len-1; i++) { + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _buf[i], SPI_CONTINUE); + } + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _buf[i]); } else { - uint16_t i; SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _cb, SPI_CONTINUE); - for (i=0; i<_len-1; i++){ + for (i=0; i<_len-1; i++) { SPI.transfer(ETHERNET_SHIELD_SPI_CS, _buf[i], SPI_CONTINUE); } SPI.transfer(ETHERNET_SHIELD_SPI_CS, _buf[i]); @@ -296,7 +332,11 @@ uint8_t W5x00Class::read(uint16_t _addr, uint8_t _cb) SPI.transfer(_addr & 0xFF); res = SPI.transfer(0); } else if (chipset == 2) { - // XXX: Missing 5200 + SPI.transfer(_addr >> 8); + SPI.transfer(_addr & 0xFF); + SPI.transfer(0x00); + SPI.transfer(0x01); + res = SPI.transfer(0); } else { SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); @@ -311,7 +351,11 @@ uint8_t W5x00Class::read(uint16_t _addr, uint8_t _cb) SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); res = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0); } else if (chipset == 2) { - // XXX: Missing 5200 + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x00, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x01, SPI_CONTINUE); + res = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0); } else { SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); @@ -337,7 +381,15 @@ uint16_t W5x00Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _ resetSS(); } } else if (chipset == 2) { - // XXX: Missing 5200 + setSS(); + SPI.transfer(_addr >> 8); + SPI.transfer(_addr & 0xFF); + SPI.transfer((_len & 0x7F00) >> 8); + SPI.transfer(_len & 0xFF); + for (uint16_t i=0; i<_len; i++){ + _buf[i] = SPI.transfer(0); + } + resetSS(); } else { setSS(); SPI.transfer(_addr >> 8); @@ -349,8 +401,9 @@ uint16_t W5x00Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _ resetSS(); } #else + uint16_t i; if (chipset == 1) { - for (uint16_t i=0; i<_len; i++) + for (i=0; i<_len; i++) { SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x0F, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); @@ -359,9 +412,15 @@ uint16_t W5x00Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _ _addr++; } } else if (chipset == 2) { - // XXX: Missing 5200 + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, (_len & 0x7F00) >> 8, SPI_CONTINUE); + SPI.transfer(ETHERNET_SHIELD_SPI_CS, _len & 0xFF, SPI_CONTINUE); + for (i=0; i<_len-1; i++){ + _buf[i] = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0, SPI_CONTINUE); + } + _buf[_len-1] = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0); } else { - uint16_t i; SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _cb, SPI_CONTINUE); diff --git a/libraries/Ethernet/src/utility/w5100.h b/libraries/Ethernet/src/utility/w5100.h index 0a36ca94607..fd33f5b745a 100644 --- a/libraries/Ethernet/src/utility/w5100.h +++ b/libraries/Ethernet/src/utility/w5100.h @@ -226,27 +226,27 @@ class W5x00Class { } 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_W5100, 0x0017); // Timeout address - __GP_REGISTER16(RTR_W5500, 0x0019); // Timeout address - __GP_REGISTER8 (RCR_W5100, 0x0019); // Retry count - __GP_REGISTER8 (RCR_W5500, 0x001B); // Retry count - __GP_REGISTER8 (RMSR, 0x001A); // Receive memory size - __GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size - __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 - __GP_REGISTER_N(UIPR_W5100, 0x002A, 4); // Unreachable IP address in UDP mode - __GP_REGISTER_N(UIPR_W5500, 0x0028, 4); // Unreachable IP address in UDP mode - __GP_REGISTER16(UPORT_W5100, 0x002E); // Unreachable Port address in UDP mode - __GP_REGISTER16(UPORT_W5500, 0x002C); // Unreachable Port address in UDP mode - __GP_REGISTER8 (PHYCFGR_W5500, 0x002E); // PHY Configuration register, default value: 0b 1011 1xxx + __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_W5100_W5200, 0x0017); // Timeout address + __GP_REGISTER16(RTR_W5500, 0x0019); // Timeout address + __GP_REGISTER8 (RCR_W5100_W5200, 0x0019); // Retry count + __GP_REGISTER8 (RCR_W5500, 0x001B); // Retry count + __GP_REGISTER8 (RMSR, 0x001A); // Receive memory size + __GP_REGISTER8 (TMSR, 0x001B); // Transmit memory size + __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 + __GP_REGISTER_N(UIPR_W5100_W5200, 0x002A, 4); // Unreachable IP address in UDP mode + __GP_REGISTER_N(UIPR_W5500, 0x0028, 4); // Unreachable IP address in UDP mode + __GP_REGISTER16(UPORT_W5100_W5200, 0x002E); // Unreachable Port address in UDP mode + __GP_REGISTER16(UPORT_W5500, 0x002C); // Unreachable Port address in UDP mode + __GP_REGISTER8 (PHYCFGR_W5500, 0x002E); // PHY Configuration register, default value: 0b 1011 1xxx #undef __GP_REGISTER8 #undef __GP_REGISTER16 @@ -375,38 +375,30 @@ class W5x00Class { extern W5x00Class W5100; uint8_t W5x00Class::readSn(SOCKET _s, uint16_t _addr) { - if (chipset == 1) + if (chipset != 5) return read(CH_BASE + _s * CH_SIZE + _addr, 0x00); - if (chipset == 2) - return 0; // XXX: TODO - if (chipset == 5) + else return read(_addr, (_s<<5) + 0x08); } uint8_t W5x00Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t _data) { - if (chipset == 1) + if (chipset != 5) return write(CH_BASE + _s * CH_SIZE + _addr, 0x00, _data); - if (chipset == 2) - return 0; // XXX: TODO - if (chipset == 5) + else return write(_addr, (_s<<5) + 0x0C, _data); } uint16_t W5x00Class::readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) { - if (chipset == 1) + if (chipset != 5) return read(CH_BASE + _s * CH_SIZE + _addr, 0x00, _buf, _len); - if (chipset == 2) - return 0; // XXX: TODO - if (chipset == 5) + else return read(_addr, (_s<<5) + 0x08, _buf, _len); } uint16_t W5x00Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) { - if (chipset == 1) + if (chipset != 5) return write(CH_BASE + _s * CH_SIZE + _addr, 0x00, _buf, _len); - if (chipset == 2) - return 0; // XXX: TODO - if (chipset == 5) + else return write(_addr, (_s<<5) + 0x0C, _buf, _len); } @@ -443,23 +435,17 @@ void W5x00Class::setIPAddress(uint8_t *_addr) { } void W5x00Class::setRetransmissionTime(uint16_t _timeout) { - if (chipset == 1) { - writeRTR_W5100(_timeout); - } else if (chipset == 2) { - // XXX: TODO - } else { + if (chipset != 5) + writeRTR_W5100_W5200(_timeout); + else writeRTR_W5500(_timeout); - } } void W5x00Class::setRetransmissionCount(uint8_t _retry) { - if (chipset == 1) { - writeRCR_W5100(_retry); - } else if (chipset == 2) { - // XXX: TODO - } else { + if (chipset != 5) + writeRCR_W5100_W5200(_retry); + else writeRCR_W5500(_retry); - } } #endif From ddecc7037e7d64faf986d0621c9ded6f77ab0bb9 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 22 Sep 2014 00:24:38 +0200 Subject: [PATCH 05/15] Ethernet: removed redundant SPI configuration --- libraries/Ethernet/src/utility/w5100.cpp | 3 --- libraries/Ethernet/src/utility/w5100.h | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/libraries/Ethernet/src/utility/w5100.cpp b/libraries/Ethernet/src/utility/w5100.cpp index abf0729e3e8..63165703521 100644 --- a/libraries/Ethernet/src/utility/w5100.cpp +++ b/libraries/Ethernet/src/utility/w5100.cpp @@ -31,9 +31,6 @@ void W5x00Class::init(void) initSS(); #else SPI.begin(ETHERNET_SHIELD_SPI_CS); - // Set clock to 4Mhz (W5100 should support up to about 14Mhz) - SPI.setClockDivider(ETHERNET_SHIELD_SPI_CS, 21); - SPI.setDataMode(ETHERNET_SHIELD_SPI_CS, SPI_MODE0); #endif /* diff --git a/libraries/Ethernet/src/utility/w5100.h b/libraries/Ethernet/src/utility/w5100.h index fd33f5b745a..6180308b036 100644 --- a/libraries/Ethernet/src/utility/w5100.h +++ b/libraries/Ethernet/src/utility/w5100.h @@ -332,6 +332,8 @@ class W5x00Class { private: #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) + // Set clock to 4Mhz (W5100 should support up to about 14Mhz) + // TODO: set SPI clock to maximum allowed for any chipset #define SPI_ETHERNET_SETTINGS SPISettings(4000000, MSBFIRST, SPI_MODE0) #if defined(ARDUINO_ARCH_AVR) #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) From ae4e1b5aaa3162013adbc4a25690d0523097db9b Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 19 Sep 2014 19:21:55 +0200 Subject: [PATCH 06/15] Ethernet: removed useless 'volatile' modifier in W5x00Class::read_data method --- libraries/Ethernet/src/utility/w5100.cpp | 10 +++++----- libraries/Ethernet/src/utility/w5100.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/Ethernet/src/utility/w5100.cpp b/libraries/Ethernet/src/utility/w5100.cpp index 63165703521..8b785c63fd0 100644 --- a/libraries/Ethernet/src/utility/w5100.cpp +++ b/libraries/Ethernet/src/utility/w5100.cpp @@ -184,21 +184,21 @@ void W5x00Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uin } } -void W5x00Class::read_data(SOCKET s, volatile uint16_t src, volatile uint8_t *dst, uint16_t len) +void W5x00Class::read_data(SOCKET s, uint16_t src, uint8_t *dst, uint16_t len) { if (chipset != 5) { uint16_t src_mask = src & RMASK; uint16_t src_ptr = RBASE[s] + src_mask; if ((src_mask + len) > RSIZE) { uint16_t size = RSIZE - src_mask; - read(src_ptr, 0x00, (uint8_t *)dst, size); + read(src_ptr, 0x00, dst, size); dst += size; - read(RBASE[s], 0x00, (uint8_t *) dst, len - size); + read(RBASE[s], 0x00, dst, len - size); } else { - read(src_ptr, 0x00, (uint8_t *) dst, len); + read(src_ptr, 0x00, dst, len); } } else { - read((uint16_t)src , (s<<5) + 0x18, (uint8_t *)dst, len); + read(src, (s<<5) + 0x18, dst, len); } } diff --git a/libraries/Ethernet/src/utility/w5100.h b/libraries/Ethernet/src/utility/w5100.h index 6180308b036..41cd05460ff 100644 --- a/libraries/Ethernet/src/utility/w5100.h +++ b/libraries/Ethernet/src/utility/w5100.h @@ -137,7 +137,7 @@ class W5x00Class { * 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 uint16_t src, volatile uint8_t * dst, uint16_t len); + void read_data(SOCKET s, uint16_t src, uint8_t *dst, uint16_t len); /** * @brief This function is being called by send() and sendto() function also. @@ -146,6 +146,7 @@ class W5x00Class { * 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 @@ -156,7 +157,6 @@ class W5x00Class { * 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); /** From 56e70c43b2e3871e3c32f2c6437960d27459c463 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Sat, 20 Sep 2014 19:40:32 +0200 Subject: [PATCH 07/15] Ethernet: use named constants for chipset --- libraries/Ethernet/src/utility/w5100.cpp | 54 ++++++++++++------------ libraries/Ethernet/src/utility/w5100.h | 19 ++++++--- 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/libraries/Ethernet/src/utility/w5100.cpp b/libraries/Ethernet/src/utility/w5100.cpp index 8b785c63fd0..2e75230f658 100644 --- a/libraries/Ethernet/src/utility/w5100.cpp +++ b/libraries/Ethernet/src/utility/w5100.cpp @@ -15,7 +15,7 @@ // W5x00 controller instance W5x00Class W5100; -uint8_t W5x00Class::chipset = 0; +uint8_t W5x00Class::chipset = W5x00Chipset::W5100; uint8_t W5x00Class::sockets = 4; #define TX_RX_MAX_BUF_SIZE 2048 @@ -46,37 +46,37 @@ void W5x00Class::init(void) SPI.transfer(testW5200, 5); resetSS(); if (testW5200[4] == 0x03) { - chipset = 2; + chipset = W5x00Chipset::W5200; } else { // Check for W5500 setSS(); SPI.transfer(testW5500, 4); resetSS(); if (testW5500[3] == 0x04) { - chipset = 5; + chipset = W5x00Chipset::W5500; } else { - chipset = 1; + chipset = W5x00Chipset::W5100; } } #else // Check for W5200 SPI.transfer(ETHERNET_SHIELD_SPI_CS, testW5200, 5); if (testW5200[4] == 0x03) { - chipset = 2; + chipset = W5x00Chipset::W5200; } else { // Check for W5500 SPI.transfer(ETHERNET_SHIELD_SPI_CS, testW5500, 4); if (testW5500[3] == 0x04) { - chipset = 5; + chipset = W5x00Chipset::W5500; } else { - chipset = 1; + chipset = W5x00Chipset::W5100; } } #endif SPI.endTransaction(); // W5x00 reset - if (chipset == 1) { + if (chipset == W5x00Chipset::W5100) { sockets = 4; SPI.beginTransaction(SPI_ETHERNET_SETTINGS); writeMR(1< SSIZE) @@ -186,7 +186,7 @@ void W5x00Class::recv_data_processing(SOCKET s, uint8_t *data, uint16_t len, uin void W5x00Class::read_data(SOCKET s, uint16_t src, uint8_t *dst, uint16_t len) { - if (chipset != 5) { + if (chipset != W5x00Chipset::W5500) { uint16_t src_mask = src & RMASK; uint16_t src_ptr = RBASE[s] + src_mask; if ((src_mask + len) > RSIZE) { @@ -207,12 +207,12 @@ uint8_t W5x00Class::write(uint16_t _addr, uint8_t _cb, uint8_t _data) { #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) setSS(); - if (chipset == 1) { + if (chipset == W5x00Chipset::W5100) { SPI.transfer(0xF0); SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); SPI.transfer(_data); - } else if (chipset == 2) { + } else if (chipset == W5x00Chipset::W5200) { SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); SPI.transfer(0x80); @@ -226,12 +226,12 @@ uint8_t W5x00Class::write(uint16_t _addr, uint8_t _cb, uint8_t _data) } resetSS(); #else - if (chipset == 1) { + if (chipset == W5x00Chipset::W5100) { SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0xF0, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _data); - } else if (chipset == 2) { + } else if (chipset == W5x00Chipset::W5200) { SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x80, SPI_CONTINUE); @@ -250,7 +250,7 @@ uint8_t W5x00Class::write(uint16_t _addr, uint8_t _cb, uint8_t _data) uint16_t W5x00Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uint16_t _len) { #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) - if (chipset == 1) { + if (chipset == W5x00Chipset::W5100) { for (uint16_t i=0; i<_len; i++) { setSS(); @@ -261,7 +261,7 @@ uint16_t W5x00Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uin SPI.transfer(_buf[i]); resetSS(); } - } else if (chipset == 2) { + } else if (chipset == W5x00Chipset::W5200) { if (_len == 0) return 0; setSS(); @@ -285,7 +285,7 @@ uint16_t W5x00Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uin } #else uint16_t i; - if (chipset == 1) { + if (chipset == W5x00Chipset::W5100) { for (i=0; i<_len; i++) { SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0xF0, SPI_CONTINUE); @@ -294,7 +294,7 @@ uint16_t W5x00Class::write(uint16_t _addr, uint8_t _cb, const uint8_t *_buf, uin SPI.transfer(ETHERNET_SHIELD_SPI_CS, _buf[i]); _addr++; } - } else if (chipset == 2) { + } else if (chipset == W5x00Chipset::W5200) { if (_len == 0) return 0; SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); @@ -323,12 +323,12 @@ uint8_t W5x00Class::read(uint16_t _addr, uint8_t _cb) uint8_t res; #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) setSS(); - if (chipset == 1) { + if (chipset == W5x00Chipset::W5100) { SPI.transfer(0x0F); SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); res = SPI.transfer(0); - } else if (chipset == 2) { + } else if (chipset == W5x00Chipset::W5200) { SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); SPI.transfer(0x00); @@ -342,12 +342,12 @@ uint8_t W5x00Class::read(uint16_t _addr, uint8_t _cb) } resetSS(); #else - if (chipset == 1) { + if (chipset == W5x00Chipset::W5100) { SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x0F, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); res = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0); - } else if (chipset == 2) { + } else if (chipset == W5x00Chipset::W5200) { SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x00, SPI_CONTINUE); @@ -366,7 +366,7 @@ uint8_t W5x00Class::read(uint16_t _addr, uint8_t _cb) uint16_t W5x00Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _len) { #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) - if (chipset == 1) { + if (chipset == W5x00Chipset::W5100) { for (uint16_t i=0; i<_len; i++) { setSS(); @@ -377,7 +377,7 @@ uint16_t W5x00Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _ _buf[i] = SPI.transfer(0); resetSS(); } - } else if (chipset == 2) { + } else if (chipset == W5x00Chipset::W5200) { setSS(); SPI.transfer(_addr >> 8); SPI.transfer(_addr & 0xFF); @@ -399,7 +399,7 @@ uint16_t W5x00Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _ } #else uint16_t i; - if (chipset == 1) { + if (chipset == W5x00Chipset::W5100) { for (i=0; i<_len; i++) { SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0x0F, SPI_CONTINUE); @@ -408,7 +408,7 @@ uint16_t W5x00Class::read(uint16_t _addr, uint8_t _cb, uint8_t *_buf, uint16_t _ _buf[i] = SPI.transfer(ETHERNET_SHIELD_SPI_CS, 0); _addr++; } - } else if (chipset == 2) { + } else if (chipset == W5x00Chipset::W5200) { SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr >> 8, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, _addr & 0xFF, SPI_CONTINUE); SPI.transfer(ETHERNET_SHIELD_SPI_CS, (_len & 0x7F00) >> 8, SPI_CONTINUE); diff --git a/libraries/Ethernet/src/utility/w5100.h b/libraries/Ethernet/src/utility/w5100.h index 41cd05460ff..c4a44f6351f 100644 --- a/libraries/Ethernet/src/utility/w5100.h +++ b/libraries/Ethernet/src/utility/w5100.h @@ -125,6 +125,13 @@ class IPPROTO { static const uint8_t RAW = 255; }; +class W5x00Chipset { +public: + static const uint8_t W5100 = 0; + static const uint8_t W5200 = 1; + static const uint8_t W5500 = 2; +}; + class W5x00Class { public: @@ -377,28 +384,28 @@ class W5x00Class { extern W5x00Class W5100; uint8_t W5x00Class::readSn(SOCKET _s, uint16_t _addr) { - if (chipset != 5) + if (chipset != W5x00Chipset::W5500) return read(CH_BASE + _s * CH_SIZE + _addr, 0x00); else return read(_addr, (_s<<5) + 0x08); } uint8_t W5x00Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t _data) { - if (chipset != 5) + if (chipset != W5x00Chipset::W5500) return write(CH_BASE + _s * CH_SIZE + _addr, 0x00, _data); else return write(_addr, (_s<<5) + 0x0C, _data); } uint16_t W5x00Class::readSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) { - if (chipset != 5) + if (chipset != W5x00Chipset::W5500) return read(CH_BASE + _s * CH_SIZE + _addr, 0x00, _buf, _len); else return read(_addr, (_s<<5) + 0x08, _buf, _len); } uint16_t W5x00Class::writeSn(SOCKET _s, uint16_t _addr, uint8_t *_buf, uint16_t _len) { - if (chipset != 5) + if (chipset != W5x00Chipset::W5500) return write(CH_BASE + _s * CH_SIZE + _addr, 0x00, _buf, _len); else return write(_addr, (_s<<5) + 0x0C, _buf, _len); @@ -437,14 +444,14 @@ void W5x00Class::setIPAddress(uint8_t *_addr) { } void W5x00Class::setRetransmissionTime(uint16_t _timeout) { - if (chipset != 5) + if (chipset != W5x00Chipset::W5500) writeRTR_W5100_W5200(_timeout); else writeRTR_W5500(_timeout); } void W5x00Class::setRetransmissionCount(uint8_t _retry) { - if (chipset != 5) + if (chipset != W5x00Chipset::W5500) writeRCR_W5100_W5200(_retry); else writeRCR_W5500(_retry); From 59bddcc31d6a00b737222db14364dc1bf09b3111 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 22 Sep 2014 00:17:48 +0200 Subject: [PATCH 08/15] Ethernet: generalized SPI_CS pin handling functions --- libraries/Ethernet/src/utility/w5100.h | 38 +++++--------------------- 1 file changed, 7 insertions(+), 31 deletions(-) diff --git a/libraries/Ethernet/src/utility/w5100.h b/libraries/Ethernet/src/utility/w5100.h index c4a44f6351f..9b2432a79e0 100644 --- a/libraries/Ethernet/src/utility/w5100.h +++ b/libraries/Ethernet/src/utility/w5100.h @@ -342,38 +342,14 @@ class W5x00Class { // Set clock to 4Mhz (W5100 should support up to about 14Mhz) // TODO: set SPI clock to maximum allowed for any chipset #define SPI_ETHERNET_SETTINGS SPISettings(4000000, MSBFIRST, SPI_MODE0) - #if defined(ARDUINO_ARCH_AVR) - #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__) - inline static void initSS() { DDRB |= _BV(6); }; - inline static void setSS() { PORTB &= ~_BV(6); }; - inline static void resetSS() { PORTB |= _BV(6); }; - #elif 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 - #elif defined(__ARDUINO_ARC__) - inline static void initSS() { pinMode(10, OUTPUT); }; - inline static void setSS() { digitalWrite(10, LOW); }; - inline static void resetSS() { digitalWrite(10, HIGH); }; + #if defined(__ARDUINO_ARC__) + inline static void initSS() { pinMode(10, OUTPUT); } + inline static void setSS() { digitalWrite(10, LOW); } + inline static void resetSS() { digitalWrite(10, HIGH); } #else - inline static void initSS() { - *portModeRegister(digitalPinToPort(ETHERNET_SHIELD_SPI_CS)) |= digitalPinToBitMask(ETHERNET_SHIELD_SPI_CS); - } - inline static void setSS() { - *portOutputRegister(digitalPinToPort(ETHERNET_SHIELD_SPI_CS)) &= ~digitalPinToBitMask(ETHERNET_SHIELD_SPI_CS); - } - inline static void resetSS() { - *portOutputRegister(digitalPinToPort(ETHERNET_SHIELD_SPI_CS)) |= digitalPinToBitMask(ETHERNET_SHIELD_SPI_CS); - } + inline static void initSS() { pinMode(ETHERNET_SHIELD_SPI_CS, OUTPUT); } + inline static void setSS() { *portOutputRegister(digitalPinToPort(ETHERNET_SHIELD_SPI_CS)) &= ~digitalPinToBitMask(ETHERNET_SHIELD_SPI_CS); } + inline static void resetSS() { *portOutputRegister(digitalPinToPort(ETHERNET_SHIELD_SPI_CS)) |= digitalPinToBitMask(ETHERNET_SHIELD_SPI_CS); } #endif #else #define SPI_ETHERNET_SETTINGS ETHERNET_SHIELD_SPI_CS,SPISettings(4000000, MSBFIRST, SPI_MODE0) From 976fe001859b8217fe4da972186218043d568e18 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 22 Sep 2014 00:37:46 +0200 Subject: [PATCH 09/15] Ethernet: set SPI speed to theoretical maximum allowed by W5100 --- libraries/Ethernet/src/utility/w5100.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libraries/Ethernet/src/utility/w5100.h b/libraries/Ethernet/src/utility/w5100.h index 9b2432a79e0..7a4f5864853 100644 --- a/libraries/Ethernet/src/utility/w5100.h +++ b/libraries/Ethernet/src/utility/w5100.h @@ -338,10 +338,9 @@ class W5x00Class { uint16_t RBASE[4]; // Rx buffer base address private: + // W5100 supports up to 14Mhz #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) - // Set clock to 4Mhz (W5100 should support up to about 14Mhz) - // TODO: set SPI clock to maximum allowed for any chipset - #define SPI_ETHERNET_SETTINGS SPISettings(4000000, MSBFIRST, SPI_MODE0) + #define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0) #if defined(__ARDUINO_ARC__) inline static void initSS() { pinMode(10, OUTPUT); } inline static void setSS() { digitalWrite(10, LOW); } @@ -352,7 +351,7 @@ class W5x00Class { inline static void resetSS() { *portOutputRegister(digitalPinToPort(ETHERNET_SHIELD_SPI_CS)) |= digitalPinToBitMask(ETHERNET_SHIELD_SPI_CS); } #endif #else - #define SPI_ETHERNET_SETTINGS ETHERNET_SHIELD_SPI_CS,SPISettings(4000000, MSBFIRST, SPI_MODE0) + #define SPI_ETHERNET_SETTINGS ETHERNET_SHIELD_SPI_CS,SPISettings(14000000, MSBFIRST, SPI_MODE0) // initSS(), setSS(), resetSS() not needed with EXTENDED_CS_PIN_HANDLING #endif }; From e7beaede19f1aa61614425f4d839efd735439a2a Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Tue, 23 Sep 2014 11:12:49 +0200 Subject: [PATCH 10/15] Ethernet: added getMaxSockets() method --- libraries/Ethernet/src/utility/w5100.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libraries/Ethernet/src/utility/w5100.h b/libraries/Ethernet/src/utility/w5100.h index 7a4f5864853..fcc0cbac02b 100644 --- a/libraries/Ethernet/src/utility/w5100.h +++ b/libraries/Ethernet/src/utility/w5100.h @@ -195,6 +195,8 @@ class W5x00Class { uint16_t getTXFreeSize(SOCKET s); uint16_t getRXReceivedSize(SOCKET s); + inline uint8_t getMaxSockets() { return sockets; } + private: static uint8_t chipset; static uint8_t sockets; From 514cb69188c961e22cc3c0d91edeef3a6026d2da Mon Sep 17 00:00:00 2001 From: Federico Vanzati Date: Fri, 10 Oct 2014 14:43:57 +0200 Subject: [PATCH 11/15] Increased the max sockets number to 8 for the W5200 module. --- libraries/Ethernet/src/utility/w5100.cpp | 2 +- libraries/Ethernet/src/utility/w5100.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/Ethernet/src/utility/w5100.cpp b/libraries/Ethernet/src/utility/w5100.cpp index 2e75230f658..69ba94bf05a 100644 --- a/libraries/Ethernet/src/utility/w5100.cpp +++ b/libraries/Ethernet/src/utility/w5100.cpp @@ -91,7 +91,7 @@ void W5x00Class::init(void) RBASE[i] = RXBUF_BASE + RSIZE * i; } } else if (chipset == W5x00Chipset::W5200) { - sockets = 4; + sockets = 8; SPI.beginTransaction(SPI_ETHERNET_SETTINGS); writeMR(1< Date: Fri, 10 Oct 2014 14:43:57 +0200 Subject: [PATCH 12/15] Removed redundant TX and RX buffer size initialization. Default value is already 2kB --- libraries/Ethernet/src/utility/w5100.cpp | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/libraries/Ethernet/src/utility/w5100.cpp b/libraries/Ethernet/src/utility/w5100.cpp index 69ba94bf05a..66e9bbbc6c3 100644 --- a/libraries/Ethernet/src/utility/w5100.cpp +++ b/libraries/Ethernet/src/utility/w5100.cpp @@ -76,12 +76,11 @@ void W5x00Class::init(void) SPI.endTransaction(); // W5x00 reset + // The default size for the RX and TX buffers is 2 kB if (chipset == W5x00Chipset::W5100) { sockets = 4; SPI.beginTransaction(SPI_ETHERNET_SETTINGS); writeMR(1< Date: Tue, 12 May 2015 15:32:41 +0200 Subject: [PATCH 13/15] Ethernet: fixed CH_BASE for W5200 --- libraries/Ethernet/src/utility/w5100.cpp | 6 +++++- libraries/Ethernet/src/utility/w5100.h | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/libraries/Ethernet/src/utility/w5100.cpp b/libraries/Ethernet/src/utility/w5100.cpp index 66e9bbbc6c3..4c940cac921 100644 --- a/libraries/Ethernet/src/utility/w5100.cpp +++ b/libraries/Ethernet/src/utility/w5100.cpp @@ -17,6 +17,7 @@ W5x00Class W5100; uint8_t W5x00Class::chipset = W5x00Chipset::W5100; uint8_t W5x00Class::sockets = 4; +uint16_t W5x00Class::CH_BASE = 0; #define TX_RX_MAX_BUF_SIZE 2048 #define TX_BUF 0x1100 @@ -79,6 +80,7 @@ void W5x00Class::init(void) // The default size for the RX and TX buffers is 2 kB if (chipset == W5x00Chipset::W5100) { sockets = 4; + CH_BASE = 0x0400; SPI.beginTransaction(SPI_ETHERNET_SETTINGS); writeMR(1< Date: Thu, 1 Dec 2016 14:40:52 +0100 Subject: [PATCH 14/15] Ethernet: use CS pin constant in ARC architecture --- libraries/Ethernet/src/utility/w5100.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/Ethernet/src/utility/w5100.h b/libraries/Ethernet/src/utility/w5100.h index 8dbf5c9b430..ebb7fb6ac28 100644 --- a/libraries/Ethernet/src/utility/w5100.h +++ b/libraries/Ethernet/src/utility/w5100.h @@ -344,9 +344,9 @@ class W5x00Class { #if !defined(SPI_HAS_EXTENDED_CS_PIN_HANDLING) #define SPI_ETHERNET_SETTINGS SPISettings(14000000, MSBFIRST, SPI_MODE0) #if defined(__ARDUINO_ARC__) - inline static void initSS() { pinMode(10, OUTPUT); } - inline static void setSS() { digitalWrite(10, LOW); } - inline static void resetSS() { digitalWrite(10, HIGH); } + inline static void initSS() { pinMode(ETHERNET_SHIELD_SPI_CS, OUTPUT); } + inline static void setSS() { digitalWrite(ETHERNET_SHIELD_SPI_CS, LOW); } + inline static void resetSS() { digitalWrite(ETHERNET_SHIELD_SPI_CS, HIGH); } #else inline static void initSS() { pinMode(ETHERNET_SHIELD_SPI_CS, OUTPUT); } inline static void setSS() { *portOutputRegister(digitalPinToPort(ETHERNET_SHIELD_SPI_CS)) &= ~digitalPinToBitMask(ETHERNET_SHIELD_SPI_CS); } From a7cbf0b8e0e7bd688bf1c5913ebee1c44b4c76df Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 1 Dec 2016 18:10:14 +0100 Subject: [PATCH 15/15] Ethernet: removed unused variable warning --- libraries/Ethernet/src/utility/socket.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/Ethernet/src/utility/socket.cpp b/libraries/Ethernet/src/utility/socket.cpp index 9254b7439e7..54dc162b240 100644 --- a/libraries/Ethernet/src/utility/socket.cpp +++ b/libraries/Ethernet/src/utility/socket.cpp @@ -362,7 +362,7 @@ uint16_t recvfrom(SOCKET s, uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t /** * @brief Wait for buffered transmission to complete. */ -void flush(SOCKET s) { +void flush(SOCKET /* s */) { // TODO }