WIZNet W5500 with additional enhancements

Fork of WIZnetInterface by WIZnet

Committer:
Helmut Tschemernjak
Date:
Tue Oct 10 20:56:13 2017 +0200
Revision:
35:fe3028eda085
Parent:
34:7d44648ec5f2
Child:
38:67e763cdde02
Added support for DHCP lease time and domain name
Enhance DHCP code to use opcode defines to make it easier to
understand and maintain.

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