This is the Interface library for WIZnet W5500 chip which forked of EthernetInterfaceW5500, WIZnetInterface and WIZ550ioInterface. This library has simple name as "W5500Interface". and can be used for Wiz550io users also.

Dependents:   EvrythngApi Websocket_Ethernet_HelloWorld_W5500 Websocket_Ethernet_W5500 CurrentWeatherData_W5500 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers W5500.cpp Source File

W5500.cpp

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