WIZNet W5500 with additional enhancements
Fork of WIZnetInterface by
arch/ext/W5500.cpp@35:fe3028eda085, 2017-10-10 (annotated)
- 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?
User | Revision | Line number | New 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 |