yangyang

Dependents:   espyun espyun

Fork of WIZnetInterface by jiang hao

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 #include "eth_arch.h"
00019 #if (not defined TARGET_WIZwiki_W7500) && (not defined TARGET_WIZwiki_W7500P) && (not defined TARGET_WIZwiki_W7500ECO)
00020 
00021 
00022 
00023 #include "mbed.h"
00024 #include "mbed_debug.h"
00025 #include "DNSClient.h"
00026 
00027 Serial pc(PA_13,PA_14);
00028 //Debug is disabled by default
00029 #if 0
00030 #define DBG(...) do{debug("%p %d %s ", this,__LINE__,__PRETTY_FUNCTION__); debug(__VA_ARGS__); } while(0);
00031 //#define DBG(x, ...) debug("[W5500:DBG]"x"\r\n", ##__VA_ARGS__);
00032 #define WARN(x, ...) debug("[W5500:WARN]"x"\r\n", ##__VA_ARGS__);
00033 #define ERR(x, ...) debug("[W5500:ERR]"x"\r\n", ##__VA_ARGS__);
00034 #else
00035 #define DBG(x, ...)
00036 #define WARN(x, ...)
00037 #define ERR(x, ...)
00038 #endif
00039 
00040 #if 1
00041 #define INFO(x, ...) debug("[W5500:INFO]"x"\r\n", ##__VA_ARGS__);
00042 #else
00043 #define INFO(x, ...)
00044 #endif
00045 
00046 #define DBG_SPI 0
00047 
00048 WIZnet_Chip* WIZnet_Chip::inst;
00049 
00050 WIZnet_Chip::WIZnet_Chip(PinName mosi, PinName miso, PinName sclk, PinName _cs, PinName _reset):
00051     cs(_cs), reset_pin(_reset)
00052 {
00053     spi = new SPI(mosi, miso, sclk);
00054     cs = 1;
00055     reset_pin = 1;
00056     inst = this;
00057     sock_any_port = SOCK_ANY_PORT_NUM;
00058 }
00059 
00060 WIZnet_Chip::WIZnet_Chip(SPI* spi, PinName _cs, PinName _reset):
00061     cs(_cs), reset_pin(_reset)
00062 {
00063     this->spi = spi;
00064     cs = 1;
00065     reset_pin = 1;
00066     inst = this;
00067     sock_any_port = SOCK_ANY_PORT_NUM;
00068 }
00069 
00070 bool WIZnet_Chip::setmac()
00071 {
00072 
00073     for (int i =0; i < 6; i++) reg_wr<uint8_t>(SHAR+i, mac[i]);
00074 
00075     return true;
00076 }
00077 
00078 // Set the IP
00079 bool WIZnet_Chip::setip()
00080 {
00081     reg_wr<uint32_t>(SIPR, ip);
00082     reg_wr<uint32_t>(GAR, gateway);
00083     reg_wr<uint32_t>(SUBR, netmask);
00084     return true;
00085 }
00086 
00087 bool WIZnet_Chip::setProtocol(int socket, Protocol p)
00088 {
00089     if (socket < 0) {
00090         return false;
00091     }
00092     sreg<uint8_t>(socket, Sn_MR, p);
00093     return true;
00094 }
00095 
00096 bool WIZnet_Chip::connect(int socket, const char * host, int port, int timeout_ms)
00097 {
00098     if (socket < 0) {
00099         return false;
00100     }
00101     sreg<uint8_t>(socket, Sn_MR, TCP);
00102     scmd(socket, OPEN);
00103     sreg_ip(socket, Sn_DIPR, host);
00104     sreg<uint16_t>(socket, Sn_DPORT, port);
00105     sreg<uint16_t>(socket, Sn_PORT, new_port());
00106     scmd(socket, CONNECT);
00107     Timer t;
00108     t.reset();
00109     t.start();
00110     while(!is_connected(socket)) {
00111         if (t.read_ms() > timeout_ms) {
00112             return false;
00113         }
00114     }
00115     return true;
00116 }
00117 
00118 bool WIZnet_Chip::gethostbyname(const char* host, uint32_t* ip)
00119 {
00120     uint32_t addr = str_to_ip(host);
00121     char buf[17];
00122     snprintf(buf, sizeof(buf), "%d.%d.%d.%d", (addr>>24)&0xff, (addr>>16)&0xff, (addr>>8)&0xff, addr&0xff);
00123     if (strcmp(buf, host) == 0) {
00124         *ip = addr;
00125         return true;
00126     }
00127     DNSClient client;
00128     if(client.lookup(host)) {
00129         *ip = client.ip;
00130         return true;
00131     }
00132     return false;
00133 }
00134 
00135 bool WIZnet_Chip::disconnect()
00136 {
00137     return true;
00138 }
00139 
00140 bool WIZnet_Chip::is_connected(int socket)
00141 {
00142     /*
00143         if (sreg<uint8_t>(socket, Sn_SR) == SOCK_ESTABLISHED) {
00144             return true;
00145         }
00146     */
00147     uint8_t tmpSn_SR;
00148     tmpSn_SR = sreg<uint8_t>(socket, Sn_SR);
00149     // packet sending is possible, when state is SOCK_CLOSE_WAIT.
00150     if ((tmpSn_SR == SOCK_ESTABLISHED) || (tmpSn_SR == SOCK_CLOSE_WAIT)) {
00151         return true;
00152     }
00153     return false;
00154 }
00155 
00156 // Reset the chip & set the buffer
00157 void WIZnet_Chip::reset()
00158 {
00159 #if defined(USE_WIZ550IO_MAC)
00160     //read the MAC address inside the module    
00161     reg_rd_mac(SHAR, mac); 
00162 #endif
00163     // hw reset
00164     reset_pin = 1;
00165     reset_pin = 0;
00166     wait_us(500); // 500us (w5500)
00167     reset_pin = 1;
00168     wait_ms(400); // 400ms (w5500)
00169 #if defined(USE_WIZ550IO_MAC)
00170     // write MAC address inside the WZTOE MAC address register
00171     reg_wr_mac(SHAR, mac);
00172 #endif
00173     // set RX and TX buffer size
00174 #if 0
00175     for (int socket = 0; socket < MAX_SOCK_NUM; socket++) {
00176         sreg<uint8_t>(socket, Sn_RXBUF_SIZE, 2);
00177         sreg<uint8_t>(socket, Sn_TXBUF_SIZE, 2);
00178     }
00179 #endif
00180 }
00181 
00182 
00183 bool WIZnet_Chip::close(int socket)
00184 {
00185     pc.printf("------------------------------------------------------------------------***\r\n");
00186     if (socket < 0) {
00187         return false;
00188     }
00189     // if not connected, return
00190     if (sreg<uint8_t>(socket, Sn_SR) == SOCK_CLOSED) {
00191         return true;
00192     }
00193     if (sreg<uint8_t>(socket, Sn_MR) == TCP) {
00194         scmd(socket, DISCON);
00195     }
00196     scmd(socket, CLOSE);
00197     sreg<uint8_t>(socket, Sn_IR, 0xff);
00198     return true;
00199 }
00200 
00201 int WIZnet_Chip::wait_readable(int socket, int wait_time_ms, int req_size)
00202 {
00203     if (socket < 0) {
00204         return -1;
00205     }
00206     Timer t;
00207     t.reset();
00208     t.start();
00209     while(1) {
00210         //int size = sreg<uint16_t>(socket, Sn_RX_RSR);
00211         // during the reading Sn_RX_RXR, it has the possible change of this register.
00212         // so read twice and get same value then use size information.
00213         int size, size2;
00214         do {
00215             size = sreg<uint16_t>(socket, Sn_RX_RSR);
00216             size2 = sreg<uint16_t>(socket, Sn_RX_RSR);
00217         } while (size != size2);
00218         
00219         if (size > req_size) {
00220             return size;
00221         }
00222         if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) {
00223             break;
00224         }
00225     }
00226     return -1;
00227 }
00228 
00229 int WIZnet_Chip::wait_writeable(int socket, int wait_time_ms, int req_size)
00230 {
00231     if (socket < 0) {
00232         return -1;
00233     }
00234     Timer t;
00235     t.reset();
00236     t.start();
00237     while(1) {
00238         //int size = sreg<uint16_t>(socket, Sn_TX_FSR);
00239         // during the reading Sn_TX_FSR, it has the possible change of this register.
00240         // so read twice and get same value then use size information.
00241         int size, size2;
00242         do {
00243             size = sreg<uint16_t>(socket, Sn_TX_FSR);
00244             size2 = sreg<uint16_t>(socket, Sn_TX_FSR);
00245         } while (size != size2);
00246         
00247         if (size > req_size) {
00248             return size;
00249         }
00250         if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) {
00251             break;
00252         }
00253     }
00254     return -1;
00255 }
00256 
00257 int WIZnet_Chip::send(int socket, const char * str, int len)
00258 {
00259     if (socket < 0) {
00260         return -1;
00261     }
00262     uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR);
00263     uint8_t cntl_byte = (0x14 + (socket << 5));
00264     spi_write(ptr, cntl_byte, (uint8_t*)str, len);
00265     sreg<uint16_t>(socket, Sn_TX_WR, ptr + len);
00266     scmd(socket, SEND);
00267     uint8_t tmp_Sn_IR;
00268     while (( (tmp_Sn_IR = sreg<uint8_t>(socket, Sn_IR)) & INT_SEND_OK) != INT_SEND_OK) {
00269         // @Jul.10, 2014 fix contant name, and udp sendto function.
00270         switch (sreg<uint8_t>(socket, Sn_SR)) {
00271             case SOCK_CLOSED :
00272                 close(socket);
00273                 return 0;
00274                 //break;
00275             case SOCK_UDP :
00276                 // ARP timeout is possible.
00277                 if ((tmp_Sn_IR & INT_TIMEOUT) == INT_TIMEOUT) {
00278                     sreg<uint8_t>(socket, Sn_IR, INT_TIMEOUT);
00279                     return 0;
00280                 }
00281                 break;
00282             default :
00283                 break;
00284         }
00285     }
00286     /*
00287         while ((sreg<uint8_t>(socket, Sn_IR) & INT_SEND_OK) != INT_SEND_OK) {
00288             if (sreg<uint8_t>(socket, Sn_SR) == CLOSED) {
00289                 close(socket);
00290                 return 0;
00291             }
00292         }
00293     */
00294     sreg<uint8_t>(socket, Sn_IR, INT_SEND_OK);
00295 
00296     return len;
00297 }
00298 
00299 int WIZnet_Chip::recv(int socket, char* buf, int len)
00300 {
00301     if (socket < 0) {
00302         return -1;
00303     }
00304     uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD);
00305     uint8_t cntl_byte = (0x18 + (socket << 5));
00306     spi_read(ptr, cntl_byte, (uint8_t*)buf, len);
00307     sreg<uint16_t>(socket, Sn_RX_RD, ptr + len);
00308     scmd(socket, RECV);
00309     return len;
00310 }
00311 
00312 int WIZnet_Chip::new_socket()
00313 {
00314     for(int s = 0; s < MAX_SOCK_NUM; s++) {
00315         if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) {
00316             return s;
00317         }
00318     }
00319     return -1;
00320 }
00321 
00322 uint16_t WIZnet_Chip::new_port()
00323 {
00324     uint16_t port = rand();
00325     port |= 49152;
00326     return port;
00327 }
00328 
00329 bool WIZnet_Chip::link(int wait_time_ms)
00330 {
00331     Timer t;
00332     t.reset();
00333     t.start();
00334     while(1) {
00335         int is_link = ethernet_link();
00336         
00337         if (is_link) {
00338             return true;
00339         }
00340         if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) {
00341             break;
00342         }
00343     }
00344     return 0;
00345 }
00346 
00347 void WIZnet_Chip::set_link(PHYMode phymode)
00348 {
00349     int speed = -1;
00350     int duplex = 0;
00351 
00352     switch(phymode) {
00353         case AutoNegotiate : speed = -1; duplex = 0; break;
00354         case HalfDuplex10  : speed = 0;  duplex = 0; break;
00355         case FullDuplex10  : speed = 0;  duplex = 1; break;
00356         case HalfDuplex100 : speed = 1;  duplex = 0; break;
00357         case FullDuplex100 : speed = 1;  duplex = 1; break;
00358     }
00359 
00360     ethernet_set_link(speed, duplex);
00361 }
00362 
00363 void WIZnet_Chip::scmd(int socket, Command cmd)
00364 {
00365     sreg<uint8_t>(socket, Sn_CR, cmd);
00366     while(sreg<uint8_t>(socket, Sn_CR));
00367 }
00368 
00369 void WIZnet_Chip::spi_write(uint16_t addr, uint8_t cb, const uint8_t *buf, uint16_t len)
00370 {
00371     cs = 0;
00372     spi->write(addr >> 8);
00373     spi->write(addr & 0xff);
00374     spi->write(cb);
00375     for(int i = 0; i < len; i++) {
00376         spi->write(buf[i]);
00377     }
00378     cs = 1;
00379 
00380 #if DBG_SPI 
00381     debug("[SPI]W %04x(%02x %d)", addr, cb, len);
00382     for(int i = 0; i < len; i++) {
00383         debug(" %02x", buf[i]);
00384         if (i > 16) {
00385             debug(" ...");
00386             break;
00387         }
00388     }
00389     debug("\r\n");
00390 #endif
00391 }
00392 
00393 void WIZnet_Chip::spi_read(uint16_t addr, uint8_t cb, uint8_t *buf, uint16_t len)
00394 {
00395     cs = 0;
00396     spi->write(addr >> 8);
00397     spi->write(addr & 0xff);
00398     spi->write(cb);
00399     for(int i = 0; i < len; i++) {
00400         buf[i] = spi->write(0);
00401     }
00402     cs = 1;
00403 
00404 #if DBG_SPI
00405     debug("[SPI]R %04x(%02x %d)", addr, cb, len);
00406     for(int i = 0; i < len; i++) {
00407         debug(" %02x", buf[i]);
00408         if (i > 16) {
00409             debug(" ...");
00410             break;
00411         }
00412     }
00413     debug("\r\n");
00414     if ((addr&0xf0ff)==0x4026 || (addr&0xf0ff)==0x4003) {
00415         wait_ms(200);
00416     }
00417 #endif
00418 }
00419 
00420 uint32_t str_to_ip(const char* str)
00421 {
00422     uint32_t ip = 0;
00423     char* p = (char*)str;
00424     for(int i = 0; i < 4; i++) {
00425         ip |= atoi(p);
00426         p = strchr(p, '.');
00427         if (p == NULL) {
00428             break;
00429         }
00430         ip <<= 8;
00431         p++;
00432     }
00433     return ip;
00434 }
00435 
00436 void printfBytes(char* str, uint8_t* buf, int len)
00437 {
00438     printf("%s %d:", str, len);
00439     for(int i = 0; i < len; i++) {
00440         printf(" %02x", buf[i]);
00441     }
00442     printf("\n");
00443 }
00444 
00445 void printHex(uint8_t* buf, int len)
00446 {
00447     for(int i = 0; i < len; i++) {
00448         if ((i%16) == 0) {
00449             printf("%p", buf+i);
00450         }
00451         printf(" %02x", buf[i]);
00452         if ((i%16) == 15) {
00453             printf("\n");
00454         }
00455     }
00456     printf("\n");
00457 }
00458 
00459 void debug_hex(uint8_t* buf, int len)
00460 {
00461     for(int i = 0; i < len; i++) {
00462         if ((i%16) == 0) {
00463             debug("%p", buf+i);
00464         }
00465         debug(" %02x", buf[i]);
00466         if ((i%16) == 15) {
00467             debug("\n");
00468         }
00469     }
00470     debug("\n");
00471 }
00472 
00473 int WIZnet_Chip::ethernet_link(void) {
00474     int val = getPHYCFGR();
00475     return (val&0x01);
00476 }
00477 
00478 void WIZnet_Chip::ethernet_set_link(int speed, int duplex) {
00479     uint32_t val=0;
00480     if((speed < 0) || (speed > 1)) {
00481         val = (PHYCFGR_OPMDC_ALLA)<<3; 
00482     } else {
00483         val = (((speed&0x01)<<1)+ (duplex&0x01))<<3; 
00484     }
00485     setPHYCFGR((uint8_t)(PHYCFGR_RST&(PHYCFGR_OPMD|val)));
00486     wait(0.2);
00487     setPHYCFGR((uint8_t)((~PHYCFGR_RST)|(PHYCFGR_OPMD|val)));
00488     wait(0.2);
00489 }
00490 
00491     void WIZnet_Chip::reg_rd_mac(uint16_t addr, uint8_t* data) {
00492         spi_read(addr, 0x00, data, 6);
00493     }
00494 
00495     void WIZnet_Chip::reg_wr_ip(uint16_t addr, uint8_t cb, const char* ip) {
00496         uint8_t buf[4];
00497         char* p = (char*)ip;
00498         for(int i = 0; i < 4; i++) {
00499             buf[i] = atoi(p);
00500             p = strchr(p, '.');
00501             if (p == NULL) {
00502                 break;
00503             }
00504             p++;
00505         }
00506         spi_write(addr, cb, buf, sizeof(buf));
00507     }
00508     
00509     void WIZnet_Chip::sreg_ip(int socket, uint16_t addr, const char* ip) {
00510         reg_wr_ip(addr, (0x0C + (socket << 5)), ip);
00511     }
00512     
00513     void WIZnet_Chip::reg_rd_ip_byte(uint16_t addr, uint8_t* data) {
00514         spi_read(addr, 0x00, data, 4);
00515     }
00516     
00517     void WIZnet_Chip::reg_wr_ip_byte(uint16_t addr, uint8_t* data) {
00518         spi_write(addr, 0x04, data, 4);
00519     }
00520 
00521 
00522 #endif
00523