This is WIZnet Ethernet Interface using Hardware TCP/IP chip, W5500, W5200 and W5100. One of them can be selected by enabling it in wiznet.h.

Dependents:   Embedded_web EmailButton EmailButton HTTPClient_Weather ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers W5500.cpp Source File

W5500.cpp

00001 /* Copyright (C) 2012 mbed.org, MIT License
00002  *
00003  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
00004  * and associated documentation files (the "Software"), to deal in the Software without restriction,
00005  * including without limitation the rights to use, copy, modify, merge, publish, distribute,
00006  * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
00007  * furnished to do so, subject to the following conditions:
00008  *
00009  * The above copyright notice and this permission notice shall be included in all copies or
00010  * substantial portions of the Software.
00011  *
00012  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
00013  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00014  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
00015  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00016  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00017  */
00018 
00019 #include "mbed.h"
00020 #include "mbed_debug.h"
00021 #include "wiznet.h"
00022 #include "DNSClient.h"
00023 
00024 #ifdef USE_W5500
00025 //Debug is disabled by default
00026 #if 0
00027 #define DBG(...) do{debug("%p %d %s ", this,__LINE__,__PRETTY_FUNCTION__); debug(__VA_ARGS__); } while(0);
00028 //#define DBG(x, ...) debug("[W5500:DBG]"x"\r\n", ##__VA_ARGS__);
00029 #define WARN(x, ...) debug("[W5500:WARN]"x"\r\n", ##__VA_ARGS__);
00030 #define ERR(x, ...) debug("[W5500:ERR]"x"\r\n", ##__VA_ARGS__);
00031 #else
00032 #define DBG(x, ...)
00033 #define WARN(x, ...)
00034 #define ERR(x, ...)
00035 #endif
00036 
00037 #if 1
00038 #define INFO(x, ...) debug("[W5500:INFO]"x"\r\n", ##__VA_ARGS__);
00039 #else
00040 #define INFO(x, ...)
00041 #endif
00042 
00043 #define DBG_SPI 0
00044 
00045 WIZnet_Chip* WIZnet_Chip::inst;
00046 
00047 WIZnet_Chip::WIZnet_Chip(PinName mosi, PinName miso, PinName sclk, PinName _cs, PinName _reset):
00048     cs(_cs), reset_pin(_reset)
00049 {
00050     spi = new SPI(mosi, miso, sclk);
00051     cs = 1;
00052     reset_pin = 1;
00053     inst = this;
00054 }
00055 
00056 WIZnet_Chip::WIZnet_Chip(SPI* spi, PinName _cs, PinName _reset):
00057     cs(_cs), reset_pin(_reset)
00058 {
00059     this->spi = spi;
00060     cs = 1;
00061     reset_pin = 1;
00062     inst = this;
00063 }
00064 
00065 // Set the IP
00066 bool WIZnet_Chip::setip()
00067 {
00068     reg_wr<uint32_t>(SIPR, ip);
00069     reg_wr<uint32_t>(GAR, gateway);
00070     reg_wr<uint32_t>(SUBR, netmask);
00071     return true;
00072 }
00073 
00074 bool WIZnet_Chip::setProtocol(int socket, Protocol p)
00075 {
00076     if (socket < 0) {
00077         return false;
00078     }
00079     sreg<uint8_t>(socket, Sn_MR, p);
00080     return true;
00081 }
00082 
00083 bool WIZnet_Chip::connect(int socket, const char * host, int port, int timeout_ms)
00084 {
00085     if (socket < 0) {
00086         return false;
00087     }
00088     sreg<uint8_t>(socket, Sn_MR, TCP);
00089     scmd(socket, OPEN);
00090     sreg_ip(socket, Sn_DIPR, host);
00091     sreg<uint16_t>(socket, Sn_DPORT, port);
00092     sreg<uint16_t>(socket, Sn_PORT, new_port());
00093     scmd(socket, CONNECT);
00094     Timer t;
00095     t.reset();
00096     t.start();
00097     while(!is_connected(socket)) {
00098         if (t.read_ms() > timeout_ms) {
00099             return false;
00100         }
00101     }
00102     return true;
00103 }
00104 
00105 bool WIZnet_Chip::gethostbyname(const char* host, uint32_t* ip)
00106 {
00107     uint32_t addr = str_to_ip(host);
00108     char buf[17];
00109     snprintf(buf, sizeof(buf), "%d.%d.%d.%d", (addr>>24)&0xff, (addr>>16)&0xff, (addr>>8)&0xff, addr&0xff);
00110     if (strcmp(buf, host) == 0) {
00111         *ip = addr;
00112         return true;
00113     }
00114     DNSClient client;
00115     if(client.lookup(host)) {
00116         *ip = client.ip;
00117         return true;
00118     }
00119     return false;
00120 }
00121 
00122 bool WIZnet_Chip::disconnect()
00123 {
00124     return true;
00125 }
00126 
00127 bool WIZnet_Chip::is_connected(int socket)
00128 {
00129     uint8_t tmpSn_SR;
00130     tmpSn_SR = sreg<uint8_t>(socket, Sn_SR);
00131     // packet sending is possible, when state is SOCK_CLOSE_WAIT.
00132     if ((tmpSn_SR == SOCK_ESTABLISHED) || (tmpSn_SR == SOCK_CLOSE_WAIT)) {
00133         return true;
00134     }
00135     return false;
00136 }
00137 
00138 
00139 bool WIZnet_Chip::is_fin_received(int socket)
00140 {
00141     uint8_t tmpSn_SR;
00142     tmpSn_SR = sreg<uint8_t>(socket, Sn_SR);
00143     // packet sending is possible, when state is SOCK_CLOSE_WAIT.
00144     if (tmpSn_SR == SOCK_CLOSE_WAIT) {
00145         return true;
00146     }
00147     return false;
00148 }
00149 // Reset the chip & set the buffer
00150 void WIZnet_Chip::reset()
00151 {
00152     reset_pin = 1;
00153     reset_pin = 0;
00154     wait_us(500); // 500us (w5500)
00155     reset_pin = 1;
00156     wait_ms(400); // 400ms (w5500)
00157 
00158 #if defined(USE_WIZ550IO_MAC)
00159     reg_rd_mac(SHAR, mac); // read the MAC address inside the module
00160 #endif
00161 
00162     reg_wr_mac(SHAR, mac);
00163 
00164     // set RX and TX buffer size
00165     for (int socket = 0; socket < MAX_SOCK_NUM; socket++) {
00166         sreg<uint8_t>(socket, Sn_RXBUF_SIZE, 2);
00167         sreg<uint8_t>(socket, Sn_TXBUF_SIZE, 2);
00168     }
00169 }
00170 
00171 
00172 bool WIZnet_Chip::close(int socket)
00173 {
00174     if (socket < 0) {
00175         return false;
00176     }
00177     // if not connected, return
00178     if (sreg<uint8_t>(socket, Sn_SR) == SOCK_CLOSED) {
00179         return true;
00180     }
00181     if (sreg<uint8_t>(socket, Sn_MR) == TCP) {
00182         scmd(socket, DISCON);
00183     }
00184     scmd(socket, CLOSE);
00185     sreg<uint8_t>(socket, Sn_IR, 0xff);
00186     return true;
00187 }
00188 
00189 int WIZnet_Chip::wait_readable(int socket, int wait_time_ms, int req_size)
00190 {
00191     if (socket < 0) {
00192         return -1;
00193     }
00194     Timer t;
00195     t.reset();
00196     t.start();
00197     while(1) {
00198         //int size = sreg<uint16_t>(socket, Sn_RX_RSR);
00199         // during the reading Sn_RX_RXR, it has the possible change of this register.
00200         // so read twice and get same value then use size information.
00201         int size, size2;
00202         do {
00203             size = sreg<uint16_t>(socket, Sn_RX_RSR);
00204             size2 = sreg<uint16_t>(socket, Sn_RX_RSR);
00205         } while (size != size2);
00206         
00207         if (size > req_size) {
00208             return size;
00209         }
00210         if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) {
00211             break;
00212         }
00213     }
00214     return -1;
00215 }
00216 
00217 int WIZnet_Chip::wait_writeable(int socket, int wait_time_ms, int req_size)
00218 {
00219     if (socket < 0) {
00220         return -1;
00221     }
00222     Timer t;
00223     t.reset();
00224     t.start();
00225     while(1) {
00226         //int size = sreg<uint16_t>(socket, Sn_TX_FSR);
00227         // during the reading Sn_TX_FSR, it has the possible change of this register.
00228         // so read twice and get same value then use size information.
00229         int size, size2;
00230         do {
00231             size = sreg<uint16_t>(socket, Sn_TX_FSR);
00232             size2 = sreg<uint16_t>(socket, Sn_TX_FSR);
00233         } while (size != size2);
00234         
00235         if (size > req_size) {
00236             return size;
00237         }
00238         if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) {
00239             break;
00240         }
00241     }
00242     return -1;
00243 }
00244 
00245 int WIZnet_Chip::send(int socket, const char * str, int len)
00246 {
00247     if (socket < 0) {
00248         return -1;
00249     }
00250     uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR);
00251     uint8_t cntl_byte = (0x14 + (socket << 5));
00252     spi_write(ptr, cntl_byte, (uint8_t*)str, len);
00253     sreg<uint16_t>(socket, Sn_TX_WR, ptr + len);
00254     scmd(socket, SEND);
00255     uint8_t tmp_Sn_IR;
00256     while (( (tmp_Sn_IR = sreg<uint8_t>(socket, Sn_IR)) & INT_SEND_OK) != INT_SEND_OK) {
00257         // @Jul.10, 2014 fix contant name, and udp sendto function.
00258         switch (sreg<uint8_t>(socket, Sn_SR)) {
00259             case SOCK_CLOSED :
00260                 close(socket);
00261                 return 0;
00262                 //break;
00263             case SOCK_UDP :
00264                 // ARP timeout is possible.
00265                 if ((tmp_Sn_IR & INT_TIMEOUT) == INT_TIMEOUT) {
00266                     sreg<uint8_t>(socket, Sn_IR, INT_TIMEOUT);
00267                     return 0;
00268                 }
00269                 break;
00270             default :
00271                 break;
00272         }
00273     }
00274     /*
00275         while ((sreg<uint8_t>(socket, Sn_IR) & INT_SEND_OK) != INT_SEND_OK) {
00276             if (sreg<uint8_t>(socket, Sn_SR) == CLOSED) {
00277                 close(socket);
00278                 return 0;
00279             }
00280         }
00281     */
00282     sreg<uint8_t>(socket, Sn_IR, INT_SEND_OK);
00283 
00284     return len;
00285 }
00286 
00287 int WIZnet_Chip::recv(int socket, char* buf, int len)
00288 {
00289     if (socket < 0) {
00290         return -1;
00291     }
00292     uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD);
00293     uint8_t cntl_byte = (0x18 + (socket << 5));
00294     spi_read(ptr, cntl_byte, (uint8_t*)buf, len);
00295     sreg<uint16_t>(socket, Sn_RX_RD, ptr + len);
00296     scmd(socket, RECV);
00297     return len;
00298 }
00299 
00300 int WIZnet_Chip::new_socket()
00301 {
00302     for(int s = 0; s < MAX_SOCK_NUM; s++) {
00303         if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) {
00304             return s;
00305         }
00306     }
00307     return -1;
00308 }
00309 
00310 uint16_t WIZnet_Chip::new_port()
00311 {
00312     uint16_t port = rand();
00313     port |= 49152;
00314     return port;
00315 }
00316 
00317 void WIZnet_Chip::scmd(int socket, Command cmd)
00318 {
00319     sreg<uint8_t>(socket, Sn_CR, cmd);
00320     while(sreg<uint8_t>(socket, Sn_CR));
00321 }
00322 
00323 void WIZnet_Chip::spi_write(uint16_t addr, uint8_t cb, const uint8_t *buf, uint16_t len)
00324 {
00325     cs = 0;
00326     spi->write(addr >> 8);
00327     spi->write(addr & 0xff);
00328     spi->write(cb);
00329     for(int i = 0; i < len; i++) {
00330         spi->write(buf[i]);
00331     }
00332     cs = 1;
00333 
00334 #if DBG_SPI
00335     debug("[SPI]W %04x(%02x %d)", addr, cb, len);
00336     for(int i = 0; i < len; i++) {
00337         debug(" %02x", buf[i]);
00338         if (i > 16) {
00339             debug(" ...");
00340             break;
00341         }
00342     }
00343     debug("\r\n");
00344 #endif
00345 }
00346 
00347 void WIZnet_Chip::spi_read(uint16_t addr, uint8_t cb, uint8_t *buf, uint16_t len)
00348 {
00349     cs = 0;
00350     spi->write(addr >> 8);
00351     spi->write(addr & 0xff);
00352     spi->write(cb);
00353     for(int i = 0; i < len; i++) {
00354         buf[i] = spi->write(0);
00355     }
00356     cs = 1;
00357 
00358 #if DBG_SPI
00359     debug("[SPI]R %04x(%02x %d)", addr, cb, len);
00360     for(int i = 0; i < len; i++) {
00361         debug(" %02x", buf[i]);
00362         if (i > 16) {
00363             debug(" ...");
00364             break;
00365         }
00366     }
00367     debug("\r\n");
00368     if ((addr&0xf0ff)==0x4026 || (addr&0xf0ff)==0x4003) {
00369         wait_ms(200);
00370     }
00371 #endif
00372 }
00373 
00374 uint32_t str_to_ip(const char* str)
00375 {
00376     uint32_t ip = 0;
00377     char* p = (char*)str;
00378     for(int i = 0; i < 4; i++) {
00379         ip |= atoi(p);
00380         p = strchr(p, '.');
00381         if (p == NULL) {
00382             break;
00383         }
00384         ip <<= 8;
00385         p++;
00386     }
00387     return ip;
00388 }
00389 
00390 void printfBytes(char* str, uint8_t* buf, int len)
00391 {
00392     printf("%s %d:", str, len);
00393     for(int i = 0; i < len; i++) {
00394         printf(" %02x", buf[i]);
00395     }
00396     printf("\n");
00397 }
00398 
00399 void printHex(uint8_t* buf, int len)
00400 {
00401     for(int i = 0; i < len; i++) {
00402         if ((i%16) == 0) {
00403             printf("%p", buf+i);
00404         }
00405         printf(" %02x", buf[i]);
00406         if ((i%16) == 15) {
00407             printf("\n");
00408         }
00409     }
00410     printf("\n");
00411 }
00412 
00413 void debug_hex(uint8_t* buf, int len)
00414 {
00415     for(int i = 0; i < len; i++) {
00416         if ((i%16) == 0) {
00417             debug("%p", buf+i);
00418         }
00419         debug(" %02x", buf[i]);
00420         if ((i%16) == 15) {
00421             debug("\n");
00422         }
00423     }
00424     debug("\n");
00425 }
00426 
00427 #endif