WIZNet W5500 with additional enhancements

Fork of WIZnetInterface by WIZnet

Committer:
Helmut Tschemernjak
Date:
Mon Oct 09 19:58:19 2017 +0200
Revision:
34:7d44648ec5f2
Parent:
33:879cfe51e66e
Child:
35:fe3028eda085
Added support for manual DNS server config or DHCP DNS config.
Now the DNS 8.8.8.8 is only a fallback if no DNS server is specified.
Replaced error() messages with printf() to avoid hanging code in error()

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Soohwan Kim 0:6f28332c466f 1 /* Copyright (C) 2012 mbed.org, MIT License
Soohwan Kim 0:6f28332c466f 2 *
Soohwan Kim 0:6f28332c466f 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
Soohwan Kim 0:6f28332c466f 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
Soohwan Kim 0:6f28332c466f 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
Soohwan Kim 0:6f28332c466f 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
Soohwan Kim 0:6f28332c466f 7 * furnished to do so, subject to the following conditions:
Soohwan Kim 0:6f28332c466f 8 *
Soohwan Kim 0:6f28332c466f 9 * The above copyright notice and this permission notice shall be included in all copies or
Soohwan Kim 0:6f28332c466f 10 * substantial portions of the Software.
Soohwan Kim 0:6f28332c466f 11 *
Soohwan Kim 0:6f28332c466f 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
Soohwan Kim 0:6f28332c466f 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Soohwan Kim 0:6f28332c466f 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
Soohwan Kim 0:6f28332c466f 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Soohwan Kim 0:6f28332c466f 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Soohwan Kim 0:6f28332c466f 17 */
embeddist 3:f8c6efc8bf83 18 #include "eth_arch.h"
embeddist 28:200e63e513a8 19 #if (not defined TARGET_WIZwiki_W7500) && (not defined TARGET_WIZwiki_W7500P) && (not defined TARGET_WIZwiki_W7500ECO)
embeddist 28:200e63e513a8 20
hjjeon 26:d07c80e18b27 21
Soohwan Kim 0:6f28332c466f 22
Soohwan Kim 0:6f28332c466f 23 #include "mbed.h"
Soohwan Kim 0:6f28332c466f 24 #include "mbed_debug.h"
Soohwan Kim 0:6f28332c466f 25 #include "DNSClient.h"
Soohwan Kim 0:6f28332c466f 26
embeddist 3:f8c6efc8bf83 27
Soohwan Kim 0:6f28332c466f 28 //Debug is disabled by default
Soohwan Kim 0:6f28332c466f 29 #if 0
Soohwan Kim 0:6f28332c466f 30 #define DBG(...) do{debug("%p %d %s ", this,__LINE__,__PRETTY_FUNCTION__); debug(__VA_ARGS__); } while(0);
Soohwan Kim 0:6f28332c466f 31 //#define DBG(x, ...) debug("[W5500:DBG]"x"\r\n", ##__VA_ARGS__);
Soohwan Kim 0:6f28332c466f 32 #define WARN(x, ...) debug("[W5500:WARN]"x"\r\n", ##__VA_ARGS__);
Soohwan Kim 0:6f28332c466f 33 #define ERR(x, ...) debug("[W5500:ERR]"x"\r\n", ##__VA_ARGS__);
Soohwan Kim 0:6f28332c466f 34 #else
Soohwan Kim 0:6f28332c466f 35 #define DBG(x, ...)
Soohwan Kim 0:6f28332c466f 36 #define WARN(x, ...)
Soohwan Kim 0:6f28332c466f 37 #define ERR(x, ...)
Soohwan Kim 0:6f28332c466f 38 #endif
Soohwan Kim 0:6f28332c466f 39
Soohwan Kim 0:6f28332c466f 40 #if 1
Soohwan Kim 0:6f28332c466f 41 #define INFO(x, ...) debug("[W5500:INFO]"x"\r\n", ##__VA_ARGS__);
Soohwan Kim 0:6f28332c466f 42 #else
Soohwan Kim 0:6f28332c466f 43 #define INFO(x, ...)
Soohwan Kim 0:6f28332c466f 44 #endif
Soohwan Kim 0:6f28332c466f 45
Soohwan Kim 0:6f28332c466f 46 #define DBG_SPI 0
Soohwan Kim 0:6f28332c466f 47
Soohwan Kim 0:6f28332c466f 48 WIZnet_Chip* WIZnet_Chip::inst;
Soohwan Kim 0:6f28332c466f 49
Soohwan Kim 0:6f28332c466f 50 WIZnet_Chip::WIZnet_Chip(PinName mosi, PinName miso, PinName sclk, PinName _cs, PinName _reset):
Soohwan Kim 0:6f28332c466f 51 cs(_cs), reset_pin(_reset)
Soohwan Kim 0:6f28332c466f 52 {
Soohwan Kim 0:6f28332c466f 53 spi = new SPI(mosi, miso, sclk);
Soohwan Kim 0:6f28332c466f 54 cs = 1;
Soohwan Kim 0:6f28332c466f 55 reset_pin = 1;
Soohwan Kim 0:6f28332c466f 56 inst = this;
Helmut Tschemernjak 34:7d44648ec5f2 57 dnsaddr = 0;
Soohwan Kim 4:4930f81bbe98 58 sock_any_port = SOCK_ANY_PORT_NUM;
Soohwan Kim 0:6f28332c466f 59 }
Soohwan Kim 0:6f28332c466f 60
Soohwan Kim 0:6f28332c466f 61 WIZnet_Chip::WIZnet_Chip(SPI* spi, PinName _cs, PinName _reset):
Soohwan Kim 0:6f28332c466f 62 cs(_cs), reset_pin(_reset)
Soohwan Kim 0:6f28332c466f 63 {
Soohwan Kim 0:6f28332c466f 64 this->spi = spi;
Soohwan Kim 0:6f28332c466f 65 cs = 1;
Soohwan Kim 0:6f28332c466f 66 reset_pin = 1;
Soohwan Kim 0:6f28332c466f 67 inst = this;
Soohwan Kim 4:4930f81bbe98 68 sock_any_port = SOCK_ANY_PORT_NUM;
Soohwan Kim 4:4930f81bbe98 69 }
Soohwan Kim 4:4930f81bbe98 70
Soohwan Kim 4:4930f81bbe98 71 bool WIZnet_Chip::setmac()
Soohwan Kim 4:4930f81bbe98 72 {
Soohwan Kim 4:4930f81bbe98 73
Soohwan Kim 4:4930f81bbe98 74 for (int i =0; i < 6; i++) reg_wr<uint8_t>(SHAR+i, mac[i]);
Soohwan Kim 4:4930f81bbe98 75
Soohwan Kim 4:4930f81bbe98 76 return true;
Soohwan Kim 0:6f28332c466f 77 }
Soohwan Kim 0:6f28332c466f 78
Soohwan Kim 0:6f28332c466f 79 // Set the IP
Soohwan Kim 0:6f28332c466f 80 bool WIZnet_Chip::setip()
Soohwan Kim 0:6f28332c466f 81 {
Soohwan Kim 0:6f28332c466f 82 reg_wr<uint32_t>(SIPR, ip);
Soohwan Kim 0:6f28332c466f 83 reg_wr<uint32_t>(GAR, gateway);
Soohwan Kim 0:6f28332c466f 84 reg_wr<uint32_t>(SUBR, netmask);
Soohwan Kim 0:6f28332c466f 85 return true;
Soohwan Kim 0:6f28332c466f 86 }
Soohwan Kim 0:6f28332c466f 87
Soohwan Kim 0:6f28332c466f 88 bool WIZnet_Chip::setProtocol(int socket, Protocol p)
Soohwan Kim 0:6f28332c466f 89 {
Soohwan Kim 0:6f28332c466f 90 if (socket < 0) {
Soohwan Kim 0:6f28332c466f 91 return false;
Soohwan Kim 0:6f28332c466f 92 }
Soohwan Kim 0:6f28332c466f 93 sreg<uint8_t>(socket, Sn_MR, p);
Soohwan Kim 0:6f28332c466f 94 return true;
Soohwan Kim 0:6f28332c466f 95 }
Soohwan Kim 0:6f28332c466f 96
Soohwan Kim 0:6f28332c466f 97 bool WIZnet_Chip::connect(int socket, const char * host, int port, int timeout_ms)
Soohwan Kim 0:6f28332c466f 98 {
Soohwan Kim 0:6f28332c466f 99 if (socket < 0) {
Soohwan Kim 0:6f28332c466f 100 return false;
Soohwan Kim 0:6f28332c466f 101 }
Soohwan Kim 0:6f28332c466f 102 sreg<uint8_t>(socket, Sn_MR, TCP);
Soohwan Kim 0:6f28332c466f 103 scmd(socket, OPEN);
Soohwan Kim 0:6f28332c466f 104 sreg_ip(socket, Sn_DIPR, host);
Soohwan Kim 0:6f28332c466f 105 sreg<uint16_t>(socket, Sn_DPORT, port);
Soohwan Kim 0:6f28332c466f 106 sreg<uint16_t>(socket, Sn_PORT, new_port());
Soohwan Kim 0:6f28332c466f 107 scmd(socket, CONNECT);
Soohwan Kim 0:6f28332c466f 108 Timer t;
Soohwan Kim 0:6f28332c466f 109 t.reset();
Soohwan Kim 0:6f28332c466f 110 t.start();
Soohwan Kim 0:6f28332c466f 111 while(!is_connected(socket)) {
Soohwan Kim 0:6f28332c466f 112 if (t.read_ms() > timeout_ms) {
Soohwan Kim 0:6f28332c466f 113 return false;
Soohwan Kim 0:6f28332c466f 114 }
Soohwan Kim 0:6f28332c466f 115 }
Soohwan Kim 0:6f28332c466f 116 return true;
Soohwan Kim 0:6f28332c466f 117 }
Soohwan Kim 0:6f28332c466f 118
Soohwan Kim 0:6f28332c466f 119 bool WIZnet_Chip::gethostbyname(const char* host, uint32_t* ip)
Soohwan Kim 0:6f28332c466f 120 {
Soohwan Kim 0:6f28332c466f 121 uint32_t addr = str_to_ip(host);
Soohwan Kim 0:6f28332c466f 122 char buf[17];
Helmut Tschemernjak 32:f6d76a55a50b 123 snprintf(buf, sizeof(buf), "%d.%d.%d.%d", (int)(addr>>24)&0xff, (int)(addr>>16)&0xff, (int)(addr>>8)&0xff, (int)addr&0xff);
Soohwan Kim 0:6f28332c466f 124 if (strcmp(buf, host) == 0) {
Soohwan Kim 0:6f28332c466f 125 *ip = addr;
Soohwan Kim 0:6f28332c466f 126 return true;
Soohwan Kim 0:6f28332c466f 127 }
Soohwan Kim 0:6f28332c466f 128 DNSClient client;
Helmut Tschemernjak 34:7d44648ec5f2 129 if(client.lookup(host, dnsaddr)) {
Soohwan Kim 0:6f28332c466f 130 *ip = client.ip;
Soohwan Kim 0:6f28332c466f 131 return true;
Soohwan Kim 0:6f28332c466f 132 }
Soohwan Kim 0:6f28332c466f 133 return false;
Soohwan Kim 0:6f28332c466f 134 }
Soohwan Kim 0:6f28332c466f 135
Soohwan Kim 0:6f28332c466f 136 bool WIZnet_Chip::disconnect()
Soohwan Kim 0:6f28332c466f 137 {
Soohwan Kim 0:6f28332c466f 138 return true;
Soohwan Kim 0:6f28332c466f 139 }
Soohwan Kim 0:6f28332c466f 140
Soohwan Kim 0:6f28332c466f 141 bool WIZnet_Chip::is_connected(int socket)
Soohwan Kim 0:6f28332c466f 142 {
Soohwan Kim 0:6f28332c466f 143 /*
Soohwan Kim 0:6f28332c466f 144 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_ESTABLISHED) {
Soohwan Kim 0:6f28332c466f 145 return true;
Soohwan Kim 0:6f28332c466f 146 }
Soohwan Kim 0:6f28332c466f 147 */
Soohwan Kim 0:6f28332c466f 148 uint8_t tmpSn_SR;
Soohwan Kim 0:6f28332c466f 149 tmpSn_SR = sreg<uint8_t>(socket, Sn_SR);
Soohwan Kim 0:6f28332c466f 150 // packet sending is possible, when state is SOCK_CLOSE_WAIT.
Soohwan Kim 0:6f28332c466f 151 if ((tmpSn_SR == SOCK_ESTABLISHED) || (tmpSn_SR == SOCK_CLOSE_WAIT)) {
Soohwan Kim 0:6f28332c466f 152 return true;
Soohwan Kim 0:6f28332c466f 153 }
Soohwan Kim 0:6f28332c466f 154 return false;
Soohwan Kim 0:6f28332c466f 155 }
Soohwan Kim 0:6f28332c466f 156
Soohwan Kim 0:6f28332c466f 157 // Reset the chip & set the buffer
Soohwan Kim 0:6f28332c466f 158 void WIZnet_Chip::reset()
Soohwan Kim 0:6f28332c466f 159 {
embeddist 3:f8c6efc8bf83 160 #if defined(USE_WIZ550IO_MAC)
embeddist 14:2101ab5ee40f 161 //read the MAC address inside the module
embeddist 14:2101ab5ee40f 162 reg_rd_mac(SHAR, mac);
embeddist 14:2101ab5ee40f 163 #endif
embeddist 3:f8c6efc8bf83 164 // hw reset
Soohwan Kim 0:6f28332c466f 165 reset_pin = 1;
Soohwan Kim 0:6f28332c466f 166 reset_pin = 0;
Soohwan Kim 0:6f28332c466f 167 wait_us(500); // 500us (w5500)
Soohwan Kim 0:6f28332c466f 168 reset_pin = 1;
Soohwan Kim 0:6f28332c466f 169 wait_ms(400); // 400ms (w5500)
embeddist 14:2101ab5ee40f 170 #if defined(USE_WIZ550IO_MAC)
Soohwan Kim 0:6f28332c466f 171 // write MAC address inside the WZTOE MAC address register
Soohwan Kim 0:6f28332c466f 172 reg_wr_mac(SHAR, mac);
embeddist 14:2101ab5ee40f 173 #endif
Soohwan Kim 0:6f28332c466f 174 // set RX and TX buffer size
Soohwan Kim 0:6f28332c466f 175 #if 0
Soohwan Kim 0:6f28332c466f 176 for (int socket = 0; socket < MAX_SOCK_NUM; socket++) {
Soohwan Kim 0:6f28332c466f 177 sreg<uint8_t>(socket, Sn_RXBUF_SIZE, 2);
Soohwan Kim 0:6f28332c466f 178 sreg<uint8_t>(socket, Sn_TXBUF_SIZE, 2);
Soohwan Kim 0:6f28332c466f 179 }
Soohwan Kim 0:6f28332c466f 180 #endif
Soohwan Kim 0:6f28332c466f 181 }
Soohwan Kim 0:6f28332c466f 182
Soohwan Kim 0:6f28332c466f 183
Soohwan Kim 0:6f28332c466f 184 bool WIZnet_Chip::close(int socket)
Soohwan Kim 0:6f28332c466f 185 {
Soohwan Kim 0:6f28332c466f 186 if (socket < 0) {
Soohwan Kim 0:6f28332c466f 187 return false;
Soohwan Kim 0:6f28332c466f 188 }
Soohwan Kim 0:6f28332c466f 189 // if not connected, return
Soohwan Kim 0:6f28332c466f 190 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_CLOSED) {
Soohwan Kim 0:6f28332c466f 191 return true;
Soohwan Kim 0:6f28332c466f 192 }
Soohwan Kim 0:6f28332c466f 193 if (sreg<uint8_t>(socket, Sn_MR) == TCP) {
Soohwan Kim 0:6f28332c466f 194 scmd(socket, DISCON);
Soohwan Kim 0:6f28332c466f 195 }
Soohwan Kim 0:6f28332c466f 196 scmd(socket, CLOSE);
Soohwan Kim 0:6f28332c466f 197 sreg<uint8_t>(socket, Sn_IR, 0xff);
Soohwan Kim 0:6f28332c466f 198 return true;
Soohwan Kim 0:6f28332c466f 199 }
Soohwan Kim 0:6f28332c466f 200
Soohwan Kim 0:6f28332c466f 201 int WIZnet_Chip::wait_readable(int socket, int wait_time_ms, int req_size)
Soohwan Kim 0:6f28332c466f 202 {
Soohwan Kim 0:6f28332c466f 203 if (socket < 0) {
Soohwan Kim 0:6f28332c466f 204 return -1;
Soohwan Kim 0:6f28332c466f 205 }
Soohwan Kim 0:6f28332c466f 206 Timer t;
Soohwan Kim 0:6f28332c466f 207 t.reset();
Soohwan Kim 0:6f28332c466f 208 t.start();
Soohwan Kim 0:6f28332c466f 209 while(1) {
Soohwan Kim 0:6f28332c466f 210 //int size = sreg<uint16_t>(socket, Sn_RX_RSR);
Soohwan Kim 0:6f28332c466f 211 // during the reading Sn_RX_RXR, it has the possible change of this register.
Soohwan Kim 0:6f28332c466f 212 // so read twice and get same value then use size information.
Soohwan Kim 0:6f28332c466f 213 int size, size2;
Soohwan Kim 0:6f28332c466f 214 do {
Soohwan Kim 0:6f28332c466f 215 size = sreg<uint16_t>(socket, Sn_RX_RSR);
Soohwan Kim 0:6f28332c466f 216 size2 = sreg<uint16_t>(socket, Sn_RX_RSR);
Soohwan Kim 0:6f28332c466f 217 } while (size != size2);
Soohwan Kim 0:6f28332c466f 218
Soohwan Kim 0:6f28332c466f 219 if (size > req_size) {
Soohwan Kim 0:6f28332c466f 220 return size;
Soohwan Kim 0:6f28332c466f 221 }
Soohwan Kim 0:6f28332c466f 222 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) {
Soohwan Kim 0:6f28332c466f 223 break;
Soohwan Kim 0:6f28332c466f 224 }
Soohwan Kim 0:6f28332c466f 225 }
Soohwan Kim 0:6f28332c466f 226 return -1;
Soohwan Kim 0:6f28332c466f 227 }
Soohwan Kim 0:6f28332c466f 228
Soohwan Kim 0:6f28332c466f 229 int WIZnet_Chip::wait_writeable(int socket, int wait_time_ms, int req_size)
Soohwan Kim 0:6f28332c466f 230 {
Soohwan Kim 0:6f28332c466f 231 if (socket < 0) {
Soohwan Kim 0:6f28332c466f 232 return -1;
Soohwan Kim 0:6f28332c466f 233 }
Soohwan Kim 0:6f28332c466f 234 Timer t;
Soohwan Kim 0:6f28332c466f 235 t.reset();
Soohwan Kim 0:6f28332c466f 236 t.start();
Soohwan Kim 0:6f28332c466f 237 while(1) {
Soohwan Kim 0:6f28332c466f 238 //int size = sreg<uint16_t>(socket, Sn_TX_FSR);
Soohwan Kim 0:6f28332c466f 239 // during the reading Sn_TX_FSR, it has the possible change of this register.
Soohwan Kim 0:6f28332c466f 240 // so read twice and get same value then use size information.
Soohwan Kim 0:6f28332c466f 241 int size, size2;
Soohwan Kim 0:6f28332c466f 242 do {
Soohwan Kim 0:6f28332c466f 243 size = sreg<uint16_t>(socket, Sn_TX_FSR);
Soohwan Kim 0:6f28332c466f 244 size2 = sreg<uint16_t>(socket, Sn_TX_FSR);
Soohwan Kim 0:6f28332c466f 245 } while (size != size2);
Soohwan Kim 0:6f28332c466f 246
Soohwan Kim 0:6f28332c466f 247 if (size > req_size) {
Soohwan Kim 0:6f28332c466f 248 return size;
Soohwan Kim 0:6f28332c466f 249 }
Soohwan Kim 0:6f28332c466f 250 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) {
Soohwan Kim 0:6f28332c466f 251 break;
Soohwan Kim 0:6f28332c466f 252 }
Soohwan Kim 0:6f28332c466f 253 }
Soohwan Kim 0:6f28332c466f 254 return -1;
Soohwan Kim 0:6f28332c466f 255 }
Soohwan Kim 0:6f28332c466f 256
Soohwan Kim 0:6f28332c466f 257 int WIZnet_Chip::send(int socket, const char * str, int len)
Soohwan Kim 0:6f28332c466f 258 {
Soohwan Kim 0:6f28332c466f 259 if (socket < 0) {
Soohwan Kim 0:6f28332c466f 260 return -1;
Soohwan Kim 0:6f28332c466f 261 }
Soohwan Kim 0:6f28332c466f 262 uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR);
Soohwan Kim 0:6f28332c466f 263 uint8_t cntl_byte = (0x14 + (socket << 5));
Soohwan Kim 0:6f28332c466f 264 spi_write(ptr, cntl_byte, (uint8_t*)str, len);
Soohwan Kim 0:6f28332c466f 265 sreg<uint16_t>(socket, Sn_TX_WR, ptr + len);
Soohwan Kim 0:6f28332c466f 266 scmd(socket, SEND);
Soohwan Kim 0:6f28332c466f 267 uint8_t tmp_Sn_IR;
Soohwan Kim 0:6f28332c466f 268 while (( (tmp_Sn_IR = sreg<uint8_t>(socket, Sn_IR)) & INT_SEND_OK) != INT_SEND_OK) {
Soohwan Kim 0:6f28332c466f 269 // @Jul.10, 2014 fix contant name, and udp sendto function.
Soohwan Kim 0:6f28332c466f 270 switch (sreg<uint8_t>(socket, Sn_SR)) {
Soohwan Kim 0:6f28332c466f 271 case SOCK_CLOSED :
Soohwan Kim 0:6f28332c466f 272 close(socket);
Soohwan Kim 0:6f28332c466f 273 return 0;
Soohwan Kim 0:6f28332c466f 274 //break;
Soohwan Kim 0:6f28332c466f 275 case SOCK_UDP :
Soohwan Kim 0:6f28332c466f 276 // ARP timeout is possible.
Soohwan Kim 0:6f28332c466f 277 if ((tmp_Sn_IR & INT_TIMEOUT) == INT_TIMEOUT) {
Soohwan Kim 0:6f28332c466f 278 sreg<uint8_t>(socket, Sn_IR, INT_TIMEOUT);
Soohwan Kim 0:6f28332c466f 279 return 0;
Soohwan Kim 0:6f28332c466f 280 }
Soohwan Kim 0:6f28332c466f 281 break;
Soohwan Kim 0:6f28332c466f 282 default :
Soohwan Kim 0:6f28332c466f 283 break;
Soohwan Kim 0:6f28332c466f 284 }
Soohwan Kim 0:6f28332c466f 285 }
Soohwan Kim 0:6f28332c466f 286 /*
Soohwan Kim 0:6f28332c466f 287 while ((sreg<uint8_t>(socket, Sn_IR) & INT_SEND_OK) != INT_SEND_OK) {
Soohwan Kim 0:6f28332c466f 288 if (sreg<uint8_t>(socket, Sn_SR) == CLOSED) {
Soohwan Kim 0:6f28332c466f 289 close(socket);
Soohwan Kim 0:6f28332c466f 290 return 0;
Soohwan Kim 0:6f28332c466f 291 }
Soohwan Kim 0:6f28332c466f 292 }
Soohwan Kim 0:6f28332c466f 293 */
Soohwan Kim 0:6f28332c466f 294 sreg<uint8_t>(socket, Sn_IR, INT_SEND_OK);
Soohwan Kim 0:6f28332c466f 295
Soohwan Kim 0:6f28332c466f 296 return len;
Soohwan Kim 0:6f28332c466f 297 }
Soohwan Kim 0:6f28332c466f 298
Soohwan Kim 0:6f28332c466f 299 int WIZnet_Chip::recv(int socket, char* buf, int len)
Soohwan Kim 0:6f28332c466f 300 {
Soohwan Kim 0:6f28332c466f 301 if (socket < 0) {
Soohwan Kim 0:6f28332c466f 302 return -1;
Soohwan Kim 0:6f28332c466f 303 }
Soohwan Kim 0:6f28332c466f 304 uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD);
Soohwan Kim 0:6f28332c466f 305 uint8_t cntl_byte = (0x18 + (socket << 5));
Soohwan Kim 0:6f28332c466f 306 spi_read(ptr, cntl_byte, (uint8_t*)buf, len);
Soohwan Kim 0:6f28332c466f 307 sreg<uint16_t>(socket, Sn_RX_RD, ptr + len);
Soohwan Kim 0:6f28332c466f 308 scmd(socket, RECV);
Soohwan Kim 0:6f28332c466f 309 return len;
Soohwan Kim 0:6f28332c466f 310 }
Soohwan Kim 0:6f28332c466f 311
Soohwan Kim 0:6f28332c466f 312 int WIZnet_Chip::new_socket()
Soohwan Kim 0:6f28332c466f 313 {
Soohwan Kim 0:6f28332c466f 314 for(int s = 0; s < MAX_SOCK_NUM; s++) {
Soohwan Kim 0:6f28332c466f 315 if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) {
Soohwan Kim 0:6f28332c466f 316 return s;
Soohwan Kim 0:6f28332c466f 317 }
Soohwan Kim 0:6f28332c466f 318 }
Soohwan Kim 0:6f28332c466f 319 return -1;
Soohwan Kim 0:6f28332c466f 320 }
Soohwan Kim 0:6f28332c466f 321
Soohwan Kim 0:6f28332c466f 322 uint16_t WIZnet_Chip::new_port()
Soohwan Kim 0:6f28332c466f 323 {
Soohwan Kim 0:6f28332c466f 324 uint16_t port = rand();
Soohwan Kim 0:6f28332c466f 325 port |= 49152;
Soohwan Kim 0:6f28332c466f 326 return port;
Soohwan Kim 0:6f28332c466f 327 }
Soohwan Kim 0:6f28332c466f 328
Soohwan Kim 8:4c02de1dbf3a 329 bool WIZnet_Chip::link(int wait_time_ms)
Soohwan Kim 8:4c02de1dbf3a 330 {
Soohwan Kim 8:4c02de1dbf3a 331 Timer t;
Soohwan Kim 8:4c02de1dbf3a 332 t.reset();
Soohwan Kim 8:4c02de1dbf3a 333 t.start();
Soohwan Kim 8:4c02de1dbf3a 334 while(1) {
Soohwan Kim 8:4c02de1dbf3a 335 int is_link = ethernet_link();
hjjeon 19:d8773cd4edc5 336
Soohwan Kim 8:4c02de1dbf3a 337 if (is_link) {
Soohwan Kim 8:4c02de1dbf3a 338 return true;
Soohwan Kim 8:4c02de1dbf3a 339 }
Soohwan Kim 8:4c02de1dbf3a 340 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) {
Soohwan Kim 8:4c02de1dbf3a 341 break;
Soohwan Kim 8:4c02de1dbf3a 342 }
Soohwan Kim 8:4c02de1dbf3a 343 }
Soohwan Kim 8:4c02de1dbf3a 344 return 0;
Soohwan Kim 8:4c02de1dbf3a 345 }
Soohwan Kim 8:4c02de1dbf3a 346
Soohwan Kim 8:4c02de1dbf3a 347 void WIZnet_Chip::set_link(PHYMode phymode)
Soohwan Kim 8:4c02de1dbf3a 348 {
Soohwan Kim 8:4c02de1dbf3a 349 int speed = -1;
Soohwan Kim 8:4c02de1dbf3a 350 int duplex = 0;
Soohwan Kim 8:4c02de1dbf3a 351
Soohwan Kim 8:4c02de1dbf3a 352 switch(phymode) {
Soohwan Kim 8:4c02de1dbf3a 353 case AutoNegotiate : speed = -1; duplex = 0; break;
Soohwan Kim 8:4c02de1dbf3a 354 case HalfDuplex10 : speed = 0; duplex = 0; break;
Soohwan Kim 8:4c02de1dbf3a 355 case FullDuplex10 : speed = 0; duplex = 1; break;
Soohwan Kim 8:4c02de1dbf3a 356 case HalfDuplex100 : speed = 1; duplex = 0; break;
Soohwan Kim 8:4c02de1dbf3a 357 case FullDuplex100 : speed = 1; duplex = 1; break;
Soohwan Kim 8:4c02de1dbf3a 358 }
Soohwan Kim 8:4c02de1dbf3a 359
Soohwan Kim 8:4c02de1dbf3a 360 ethernet_set_link(speed, duplex);
Soohwan Kim 8:4c02de1dbf3a 361 }
Soohwan Kim 8:4c02de1dbf3a 362
Soohwan Kim 0:6f28332c466f 363 void WIZnet_Chip::scmd(int socket, Command cmd)
Soohwan Kim 0:6f28332c466f 364 {
Soohwan Kim 0:6f28332c466f 365 sreg<uint8_t>(socket, Sn_CR, cmd);
Soohwan Kim 0:6f28332c466f 366 while(sreg<uint8_t>(socket, Sn_CR));
Soohwan Kim 0:6f28332c466f 367 }
Soohwan Kim 0:6f28332c466f 368
Soohwan Kim 0:6f28332c466f 369 void WIZnet_Chip::spi_write(uint16_t addr, uint8_t cb, const uint8_t *buf, uint16_t len)
Soohwan Kim 0:6f28332c466f 370 {
Soohwan Kim 0:6f28332c466f 371 cs = 0;
Soohwan Kim 0:6f28332c466f 372 spi->write(addr >> 8);
Soohwan Kim 0:6f28332c466f 373 spi->write(addr & 0xff);
Soohwan Kim 0:6f28332c466f 374 spi->write(cb);
Soohwan Kim 0:6f28332c466f 375 for(int i = 0; i < len; i++) {
Soohwan Kim 0:6f28332c466f 376 spi->write(buf[i]);
Soohwan Kim 0:6f28332c466f 377 }
Soohwan Kim 0:6f28332c466f 378 cs = 1;
Soohwan Kim 0:6f28332c466f 379
embeddist 14:2101ab5ee40f 380 #if DBG_SPI
Soohwan Kim 0:6f28332c466f 381 debug("[SPI]W %04x(%02x %d)", addr, cb, len);
Soohwan Kim 0:6f28332c466f 382 for(int i = 0; i < len; i++) {
Soohwan Kim 0:6f28332c466f 383 debug(" %02x", buf[i]);
Soohwan Kim 0:6f28332c466f 384 if (i > 16) {
Soohwan Kim 0:6f28332c466f 385 debug(" ...");
Soohwan Kim 0:6f28332c466f 386 break;
Soohwan Kim 0:6f28332c466f 387 }
Soohwan Kim 0:6f28332c466f 388 }
Soohwan Kim 0:6f28332c466f 389 debug("\r\n");
Soohwan Kim 0:6f28332c466f 390 #endif
Soohwan Kim 0:6f28332c466f 391 }
Soohwan Kim 0:6f28332c466f 392
Soohwan Kim 0:6f28332c466f 393 void WIZnet_Chip::spi_read(uint16_t addr, uint8_t cb, uint8_t *buf, uint16_t len)
Soohwan Kim 0:6f28332c466f 394 {
Soohwan Kim 0:6f28332c466f 395 cs = 0;
Soohwan Kim 0:6f28332c466f 396 spi->write(addr >> 8);
Soohwan Kim 0:6f28332c466f 397 spi->write(addr & 0xff);
Soohwan Kim 0:6f28332c466f 398 spi->write(cb);
Soohwan Kim 0:6f28332c466f 399 for(int i = 0; i < len; i++) {
Soohwan Kim 0:6f28332c466f 400 buf[i] = spi->write(0);
Soohwan Kim 0:6f28332c466f 401 }
Soohwan Kim 0:6f28332c466f 402 cs = 1;
Soohwan Kim 0:6f28332c466f 403
Soohwan Kim 0:6f28332c466f 404 #if DBG_SPI
Soohwan Kim 0:6f28332c466f 405 debug("[SPI]R %04x(%02x %d)", addr, cb, len);
Soohwan Kim 0:6f28332c466f 406 for(int i = 0; i < len; i++) {
Soohwan Kim 0:6f28332c466f 407 debug(" %02x", buf[i]);
Soohwan Kim 0:6f28332c466f 408 if (i > 16) {
Soohwan Kim 0:6f28332c466f 409 debug(" ...");
Soohwan Kim 0:6f28332c466f 410 break;
Soohwan Kim 0:6f28332c466f 411 }
Soohwan Kim 0:6f28332c466f 412 }
Soohwan Kim 0:6f28332c466f 413 debug("\r\n");
Soohwan Kim 0:6f28332c466f 414 if ((addr&0xf0ff)==0x4026 || (addr&0xf0ff)==0x4003) {
Soohwan Kim 0:6f28332c466f 415 wait_ms(200);
Soohwan Kim 0:6f28332c466f 416 }
Soohwan Kim 0:6f28332c466f 417 #endif
Soohwan Kim 0:6f28332c466f 418 }
Soohwan Kim 0:6f28332c466f 419
Soohwan Kim 0:6f28332c466f 420 uint32_t str_to_ip(const char* str)
Soohwan Kim 0:6f28332c466f 421 {
Soohwan Kim 0:6f28332c466f 422 uint32_t ip = 0;
Soohwan Kim 0:6f28332c466f 423 char* p = (char*)str;
Soohwan Kim 0:6f28332c466f 424 for(int i = 0; i < 4; i++) {
Soohwan Kim 0:6f28332c466f 425 ip |= atoi(p);
Soohwan Kim 0:6f28332c466f 426 p = strchr(p, '.');
Soohwan Kim 0:6f28332c466f 427 if (p == NULL) {
Soohwan Kim 0:6f28332c466f 428 break;
Soohwan Kim 0:6f28332c466f 429 }
Soohwan Kim 0:6f28332c466f 430 ip <<= 8;
Soohwan Kim 0:6f28332c466f 431 p++;
Soohwan Kim 0:6f28332c466f 432 }
Soohwan Kim 0:6f28332c466f 433 return ip;
Soohwan Kim 0:6f28332c466f 434 }
Soohwan Kim 0:6f28332c466f 435
Soohwan Kim 0:6f28332c466f 436 void printfBytes(char* str, uint8_t* buf, int len)
Soohwan Kim 0:6f28332c466f 437 {
Soohwan Kim 0:6f28332c466f 438 printf("%s %d:", str, len);
Soohwan Kim 0:6f28332c466f 439 for(int i = 0; i < len; i++) {
Soohwan Kim 0:6f28332c466f 440 printf(" %02x", buf[i]);
Soohwan Kim 0:6f28332c466f 441 }
Soohwan Kim 0:6f28332c466f 442 printf("\n");
Soohwan Kim 0:6f28332c466f 443 }
Soohwan Kim 0:6f28332c466f 444
Soohwan Kim 0:6f28332c466f 445 void printHex(uint8_t* buf, int len)
Soohwan Kim 0:6f28332c466f 446 {
Soohwan Kim 0:6f28332c466f 447 for(int i = 0; i < len; i++) {
Soohwan Kim 0:6f28332c466f 448 if ((i%16) == 0) {
Soohwan Kim 0:6f28332c466f 449 printf("%p", buf+i);
Soohwan Kim 0:6f28332c466f 450 }
Soohwan Kim 0:6f28332c466f 451 printf(" %02x", buf[i]);
Soohwan Kim 0:6f28332c466f 452 if ((i%16) == 15) {
Soohwan Kim 0:6f28332c466f 453 printf("\n");
Soohwan Kim 0:6f28332c466f 454 }
Soohwan Kim 0:6f28332c466f 455 }
Soohwan Kim 0:6f28332c466f 456 printf("\n");
Soohwan Kim 0:6f28332c466f 457 }
Soohwan Kim 0:6f28332c466f 458
Soohwan Kim 0:6f28332c466f 459 void debug_hex(uint8_t* buf, int len)
Soohwan Kim 0:6f28332c466f 460 {
Soohwan Kim 0:6f28332c466f 461 for(int i = 0; i < len; i++) {
Soohwan Kim 0:6f28332c466f 462 if ((i%16) == 0) {
Soohwan Kim 0:6f28332c466f 463 debug("%p", buf+i);
Soohwan Kim 0:6f28332c466f 464 }
Soohwan Kim 0:6f28332c466f 465 debug(" %02x", buf[i]);
Soohwan Kim 0:6f28332c466f 466 if ((i%16) == 15) {
Soohwan Kim 0:6f28332c466f 467 debug("\n");
Soohwan Kim 0:6f28332c466f 468 }
Soohwan Kim 0:6f28332c466f 469 }
Soohwan Kim 0:6f28332c466f 470 debug("\n");
Soohwan Kim 0:6f28332c466f 471 }
Soohwan Kim 0:6f28332c466f 472
embeddist 14:2101ab5ee40f 473 int WIZnet_Chip::ethernet_link(void) {
embeddist 14:2101ab5ee40f 474 int val = getPHYCFGR();
Helmut Tschemernjak 33:879cfe51e66e 475 return val & 0x01;
Helmut Tschemernjak 33:879cfe51e66e 476 }
Helmut Tschemernjak 33:879cfe51e66e 477
Helmut Tschemernjak 33:879cfe51e66e 478 int WIZnet_Chip::ethernet_speed(void) {
Helmut Tschemernjak 33:879cfe51e66e 479 int val = getPHYCFGR();
Helmut Tschemernjak 33:879cfe51e66e 480 return val &0x02 ? 100 : 10;
Soohwan Kim 8:4c02de1dbf3a 481 }
Soohwan Kim 8:4c02de1dbf3a 482
Helmut Tschemernjak 33:879cfe51e66e 483 bool WIZnet_Chip::ethernet_fullduplex(void) {
Helmut Tschemernjak 33:879cfe51e66e 484 int val = getPHYCFGR();
Helmut Tschemernjak 33:879cfe51e66e 485 return val & 0x04;
Helmut Tschemernjak 33:879cfe51e66e 486 }
Helmut Tschemernjak 33:879cfe51e66e 487
Helmut Tschemernjak 33:879cfe51e66e 488
Helmut Tschemernjak 33:879cfe51e66e 489
embeddist 14:2101ab5ee40f 490 void WIZnet_Chip::ethernet_set_link(int speed, int duplex) {
Soohwan Kim 8:4c02de1dbf3a 491 uint32_t val=0;
Soohwan Kim 8:4c02de1dbf3a 492 if((speed < 0) || (speed > 1)) {
Soohwan Kim 11:b319c1859f9b 493 val = (PHYCFGR_OPMDC_ALLA)<<3;
Soohwan Kim 8:4c02de1dbf3a 494 } else {
Soohwan Kim 8:4c02de1dbf3a 495 val = (((speed&0x01)<<1)+ (duplex&0x01))<<3;
Soohwan Kim 8:4c02de1dbf3a 496 }
embeddist 14:2101ab5ee40f 497 setPHYCFGR((uint8_t)(PHYCFGR_RST&(PHYCFGR_OPMD|val)));
Soohwan Kim 12:99e8386ba225 498 wait(0.2);
embeddist 14:2101ab5ee40f 499 setPHYCFGR((uint8_t)((~PHYCFGR_RST)|(PHYCFGR_OPMD|val)));
Soohwan Kim 12:99e8386ba225 500 wait(0.2);
Soohwan Kim 8:4c02de1dbf3a 501 }
Soohwan Kim 8:4c02de1dbf3a 502
embeddist 14:2101ab5ee40f 503 void WIZnet_Chip::reg_rd_mac(uint16_t addr, uint8_t* data) {
embeddist 14:2101ab5ee40f 504 spi_read(addr, 0x00, data, 6);
embeddist 14:2101ab5ee40f 505 }
embeddist 14:2101ab5ee40f 506
embeddist 14:2101ab5ee40f 507 void WIZnet_Chip::reg_wr_ip(uint16_t addr, uint8_t cb, const char* ip) {
embeddist 14:2101ab5ee40f 508 uint8_t buf[4];
embeddist 14:2101ab5ee40f 509 char* p = (char*)ip;
embeddist 14:2101ab5ee40f 510 for(int i = 0; i < 4; i++) {
embeddist 14:2101ab5ee40f 511 buf[i] = atoi(p);
embeddist 14:2101ab5ee40f 512 p = strchr(p, '.');
embeddist 14:2101ab5ee40f 513 if (p == NULL) {
embeddist 14:2101ab5ee40f 514 break;
embeddist 14:2101ab5ee40f 515 }
embeddist 14:2101ab5ee40f 516 p++;
embeddist 14:2101ab5ee40f 517 }
embeddist 14:2101ab5ee40f 518 spi_write(addr, cb, buf, sizeof(buf));
embeddist 14:2101ab5ee40f 519 }
embeddist 14:2101ab5ee40f 520
embeddist 14:2101ab5ee40f 521 void WIZnet_Chip::sreg_ip(int socket, uint16_t addr, const char* ip) {
embeddist 14:2101ab5ee40f 522 reg_wr_ip(addr, (0x0C + (socket << 5)), ip);
embeddist 14:2101ab5ee40f 523 }
embeddist 14:2101ab5ee40f 524
embeddist 14:2101ab5ee40f 525 void WIZnet_Chip::reg_rd_ip_byte(uint16_t addr, uint8_t* data) {
embeddist 14:2101ab5ee40f 526 spi_read(addr, 0x00, data, 4);
embeddist 14:2101ab5ee40f 527 }
embeddist 14:2101ab5ee40f 528
embeddist 14:2101ab5ee40f 529 void WIZnet_Chip::reg_wr_ip_byte(uint16_t addr, uint8_t* data) {
embeddist 14:2101ab5ee40f 530 spi_write(addr, 0x04, data, 4);
embeddist 14:2101ab5ee40f 531 }
embeddist 14:2101ab5ee40f 532
embeddist 14:2101ab5ee40f 533
Soohwan Kim 0:6f28332c466f 534 #endif
embeddist 3:f8c6efc8bf83 535