Update of W5500 Interface for mbed-os

Dependents:   PwrCond_mbed5

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