Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: DualNetworkInterface-Basic
Fork of WIZnetInterface by
W7500x_toe.cpp
00001 /* Copyright (C) 2012 mbed.org, MIT License 00002 * 00003 * and associated documentation files (the "Software"), to deal in the Software without restriction, 00004 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 00005 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 00006 * furnished to do so, subject to the following conditions: 00007 * 00008 * The above copyright notice and this permission notice shall be included in all copies or 00009 * substantial portions of the Software. 00010 * 00011 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00012 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00013 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00014 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00015 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00016 */ 00017 #include "eth_arch.hpp" 00018 #if defined(TARGET_WIZwiki_W7500) 00019 00020 #include "mbed.h" 00021 #include "mbed_debug.h" 00022 #include "DNSClient.hpp" 00023 00024 using namespace wiznet_space; 00025 00026 /* 00027 * MDIO via GPIO 00028 * mdio via gpio is supported and related functions as follows. 00029 * - mdio_init(),mdio_read(),mdio_write() 00030 * - input_MDIO(),output_MDIO(),turnaroud_MDIO(),idle_MDIO() 00031 * called by ethernet_link() and ethernet_set_link() 00032 */ 00033 #define MDIO GPIO_Pin_14 00034 #define MDC GPIO_Pin_15 00035 #define GPIO_MDC GPIOB 00036 #define PHY_ADDR_IP101G 0x07 00037 #define PHY_ADDR PHY_ADDR_IP101G 00038 #define SVAL 0x2 //right shift val = 2 00039 #define PHYREG_CONTROL 0x0 //Control Register address (Contorl basic register) 00040 #define PHYREG_STATUS 0x1 //Status Register address (Status basic register) 00041 #define CNTL_DUPLEX (0x01ul<< 7) 00042 #define CNTL_AUTONEGO (0x01ul<<11) 00043 #define CNTL_SPEED (0x01ul<<12) 00044 #define MDC_WAIT (1) 00045 void mdio_init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin_MDC, uint16_t GPIO_Pin_MDIO); 00046 void mdio_write(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr, uint32_t val); 00047 uint32_t mdio_read(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr); 00048 00049 WIZnet_Chip* WIZnet_Chip::inst; 00050 00051 WIZnet_Chip::WIZnet_Chip() 00052 { 00053 inst = this; 00054 } 00055 00056 bool WIZnet_Chip::setmac() 00057 { 00058 00059 for (int i =0; i < 6; i++) reg_wr<uint8_t>(SHAR+i, mac[i]); 00060 00061 return true; 00062 } 00063 00064 // Set the IP 00065 bool WIZnet_Chip::setip() 00066 { 00067 reg_wr<uint32_t>(SIPR, ip); 00068 reg_wr<uint32_t>(GAR, gateway); 00069 reg_wr<uint32_t>(SUBR, netmask); 00070 return true; 00071 } 00072 00073 bool WIZnet_Chip::setProtocol(int socket, Protocol p) 00074 { 00075 if (socket < 0) { 00076 return false; 00077 } 00078 sreg<uint8_t>(socket, Sn_MR, p); 00079 return true; 00080 } 00081 00082 bool WIZnet_Chip::connect(int socket, const char * host, int port, int timeout_ms) 00083 { 00084 if (socket < 0) { 00085 return false; 00086 } 00087 sreg<uint8_t>(socket, Sn_MR, TCP); 00088 scmd(socket, OPEN); 00089 sreg_ip(socket, Sn_DIPR, host); 00090 sreg<uint16_t>(socket, Sn_DPORT, port); 00091 sreg<uint16_t>(socket, Sn_PORT, new_port()); 00092 scmd(socket, CONNECT); 00093 Timer t; 00094 t.reset(); 00095 t.start(); 00096 while(!is_connected(socket)) { 00097 if (t.read_ms() > timeout_ms) { 00098 return false; 00099 } 00100 } 00101 return true; 00102 } 00103 00104 bool WIZnet_Chip::gethostbyname(const char* host, uint32_t* ip) 00105 { 00106 uint32_t addr = str_to_ip(host); 00107 char buf[17]; 00108 snprintf(buf, sizeof(buf), "%d.%d.%d.%d", 00109 (uint8_t)((addr>>24)&0xff), 00110 (uint8_t)((addr>>16)&0xff), 00111 (uint8_t)((addr>>8)&0xff), 00112 (uint8_t)(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 00126 bool WIZnet_Chip::is_connected(int socket) 00127 { 00128 /* 00129 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_ESTABLISHED) { 00130 return true; 00131 } 00132 */ 00133 uint8_t tmpSn_SR; 00134 tmpSn_SR = sreg<uint8_t>(socket, Sn_SR); 00135 // packet sending is possible, when state is SOCK_CLOSE_WAIT. 00136 if ((tmpSn_SR == SOCK_ESTABLISHED) || (tmpSn_SR == SOCK_CLOSE_WAIT)) { 00137 return true; 00138 } 00139 return false; 00140 } 00141 // Reset the chip & set the buffer 00142 void WIZnet_Chip::reset() 00143 { 00144 /* S/W Reset PHY */ 00145 mdio_write(GPIO_MDC, PHYREG_CONTROL, 0x8000); 00146 wait_ms(10);//for S/W reset 00147 wait_ms(10);//for MDC I/F RDY 00148 00149 mdio_init(GPIO_MDC, MDC, MDIO); 00150 00151 /* S/W Reset WZTOE */ 00152 reg_wr<uint8_t>(MR, MR_RST); 00153 // set PAD strengh and pull-up for TXD[3:0] and TXE 00154 #ifdef __DEF_USED_IC101AG__ //For using IC+101AG 00155 *(volatile uint32_t *)(0x41003068) = 0x64; //TXD0 00156 *(volatile uint32_t *)(0x4100306C) = 0x64; //TXD1 00157 *(volatile uint32_t *)(0x41003070) = 0x64; //TXD2 00158 *(volatile uint32_t *)(0x41003074) = 0x64; //TXD3 00159 *(volatile uint32_t *)(0x41003050) = 0x64; //TXE 00160 #endif 00161 // set ticker counter 00162 reg_wr<uint32_t>(TIC100US, (SystemCoreClock/10000)); 00163 // write MAC address inside the WZTOE MAC address register 00164 reg_wr_mac(SHAR, mac); 00165 /* 00166 * set RX and TX buffer size 00167 * for (int socket = 0; socket < MAX_SOCK_NUM; socket++) { 00168 * sreg<uint8_t>(socket, Sn_RXBUF_SIZE, 2); 00169 * sreg<uint8_t>(socket, Sn_TXBUF_SIZE, 2); 00170 * } 00171 */ 00172 } 00173 00174 00175 bool WIZnet_Chip::close(int socket) 00176 { 00177 if (socket < 0) { 00178 return false; 00179 } 00180 // if SOCK_CLOSED, return 00181 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_CLOSED) { 00182 return true; 00183 } 00184 // if SOCK_ESTABLISHED, send FIN-Packet to peer 00185 if (sreg<uint8_t>(socket, Sn_MR) == TCP) { 00186 scmd(socket, DISCON); 00187 } 00188 // close socket 00189 scmd(socket, CLOSE); 00190 // clear Socket Interrupt Register 00191 sreg<uint8_t>(socket, Sn_ICR, 0xff); 00192 return true; 00193 } 00194 00195 int WIZnet_Chip::wait_readable(int socket, int wait_time_ms, int req_size) 00196 { 00197 if (socket < 0) { 00198 return -1; 00199 } 00200 Timer t; 00201 t.reset(); 00202 t.start(); 00203 while(1) { 00204 int size = sreg<uint16_t>(socket, Sn_RX_RSR); 00205 if (size > req_size) { 00206 return size; 00207 } 00208 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00209 break; 00210 } 00211 } 00212 return -1; 00213 } 00214 00215 int WIZnet_Chip::wait_writeable(int socket, int wait_time_ms, int req_size) 00216 { 00217 if (socket < 0) { 00218 return -1; 00219 } 00220 Timer t; 00221 t.reset(); 00222 t.start(); 00223 while(1) { 00224 int size = sreg<uint16_t>(socket, Sn_TX_FSR); 00225 if (size > req_size) { 00226 return size; 00227 } 00228 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00229 break; 00230 } 00231 } 00232 return -1; 00233 } 00234 00235 int WIZnet_Chip::send(int socket, const char * str, int len) 00236 { 00237 if (socket < 0) { 00238 return -1; 00239 } 00240 00241 uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR); 00242 uint32_t sn_tx_base = W7500x_TXMEM_BASE + (uint32_t)(socket<<18); 00243 00244 for(int i=0; i<len; i++) 00245 *(volatile uint8_t *)(sn_tx_base + ((ptr+i)&0xFFFF)) = str[i]; 00246 00247 sreg<uint16_t>(socket, Sn_TX_WR, ptr + len); 00248 scmd(socket, SEND); 00249 00250 uint8_t tmp_Sn_IR; 00251 while (( (tmp_Sn_IR = sreg<uint8_t>(socket, Sn_IR)) & INT_SEND_OK) != INT_SEND_OK) { 00252 // @Jul.10, 2014 fix contant name, and udp sendto function. 00253 switch (sreg<uint8_t>(socket, Sn_SR)) { 00254 case SOCK_CLOSED : 00255 close(socket); 00256 return 0; 00257 //break; 00258 case SOCK_UDP : 00259 // ARP timeout is possible. 00260 if ((tmp_Sn_IR & INT_TIMEOUT) == INT_TIMEOUT) { 00261 sreg<uint8_t>(socket, Sn_ICR, INT_TIMEOUT); 00262 return 0; 00263 } 00264 break; 00265 default : 00266 break; 00267 } 00268 } 00269 00270 sreg<uint8_t>(socket, Sn_ICR, INT_SEND_OK); 00271 00272 return len; 00273 } 00274 00275 int WIZnet_Chip::recv(int socket, char* buf, int len) 00276 { 00277 if (socket < 0) { 00278 return -1; 00279 } 00280 uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD); 00281 uint32_t sn_rx_base = W7500x_RXMEM_BASE + (uint32_t)(socket<<18); 00282 00283 for(int i=0; i<len; i++) 00284 buf[i] = *(volatile uint8_t *)(sn_rx_base + ((ptr+i)&0xFFFF)); 00285 00286 sreg<uint16_t>(socket, Sn_RX_RD, ptr + len); 00287 scmd(socket, RECV); 00288 00289 return len; 00290 } 00291 00292 int WIZnet_Chip::new_socket() 00293 { 00294 for(int s = 0; s < MAX_SOCK_NUM; s++) { 00295 if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) { 00296 return s; 00297 } 00298 } 00299 return -1; 00300 } 00301 00302 uint16_t WIZnet_Chip::new_port() 00303 { 00304 uint16_t port = rand(); 00305 port |= 49152; 00306 return port; 00307 } 00308 00309 bool WIZnet_Chip::link(int wait_time_ms) 00310 { 00311 Timer t; 00312 t.reset(); 00313 t.start(); 00314 while(1) { 00315 int is_link = ethernet_link(); 00316 00317 if (is_link) { 00318 return true; 00319 } 00320 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00321 break; 00322 } 00323 } 00324 return 0; 00325 } 00326 00327 void WIZnet_Chip::set_link(PHYMode phymode) 00328 { 00329 int speed = -1; 00330 int duplex = 0; 00331 00332 switch(phymode) { 00333 case AutoNegotiate : speed = -1; duplex = 0; break; 00334 case HalfDuplex10 : speed = 0; duplex = 0; break; 00335 case FullDuplex10 : speed = 0; duplex = 1; break; 00336 case HalfDuplex100 : speed = 1; duplex = 0; break; 00337 case FullDuplex100 : speed = 1; duplex = 1; break; 00338 } 00339 00340 ethernet_set_link(speed, duplex); 00341 } 00342 00343 uint32_t str_to_ip(const char* str) 00344 { 00345 uint32_t ip = 0; 00346 char* p = (char*)str; 00347 for(int i = 0; i < 4; i++) { 00348 ip |= atoi(p); 00349 p = strchr(p, '.'); 00350 if (p == NULL) { 00351 break; 00352 } 00353 ip <<= 8; 00354 p++; 00355 } 00356 return ip; 00357 } 00358 00359 void printfBytes(char* str, uint8_t* buf, int len) 00360 { 00361 printf("%s %d:", str, len); 00362 for(int i = 0; i < len; i++) { 00363 printf(" %02x", buf[i]); 00364 } 00365 printf("\n"); 00366 } 00367 00368 void printHex(uint8_t* buf, int len) 00369 { 00370 for(int i = 0; i < len; i++) { 00371 if ((i%16) == 0) { 00372 printf("%p", buf+i); 00373 } 00374 printf(" %02x", buf[i]); 00375 if ((i%16) == 15) { 00376 printf("\n"); 00377 } 00378 } 00379 printf("\n"); 00380 } 00381 00382 void debug_hex(uint8_t* buf, int len) 00383 { 00384 for(int i = 0; i < len; i++) { 00385 if ((i%16) == 0) { 00386 debug("%p", buf+i); 00387 } 00388 debug(" %02x", buf[i]); 00389 if ((i%16) == 15) { 00390 debug("\n"); 00391 } 00392 } 00393 debug("\n"); 00394 } 00395 00396 void WIZnet_Chip::scmd(int socket, Command cmd) 00397 { 00398 sreg<uint8_t>(socket, Sn_CR, cmd); 00399 while(sreg<uint8_t>(socket, Sn_CR)); 00400 } 00401 00402 00403 void mdio_init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin_MDC, uint16_t GPIO_Pin_MDIO) 00404 { 00405 /* Set GPIOs for MDIO and MDC */ 00406 GPIO_InitTypeDef MDIO_InitDef; 00407 HAL_PAD_AFConfig(PAD_PB, GPIO_Pin_MDIO, PAD_AF1); 00408 HAL_PAD_AFConfig(PAD_PB, GPIO_Pin_MDC, PAD_AF1); 00409 MDIO_InitDef.GPIO_Pin = GPIO_Pin_MDC | GPIO_Pin_MDIO; 00410 MDIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; 00411 HAL_GPIO_Init(GPIOx, &MDIO_InitDef); 00412 } 00413 00414 void output_MDIO(GPIO_TypeDef* GPIOx, uint32_t val, uint32_t n) 00415 { 00416 for(val <<= (32-n); n; val<<=1, n--) 00417 { 00418 if(val & 0x80000000) 00419 HAL_GPIO_SetBits(GPIOx, MDIO); 00420 else 00421 HAL_GPIO_ResetBits(GPIOx, MDIO); 00422 00423 wait_ms(MDC_WAIT); 00424 HAL_GPIO_SetBits(GPIOx, MDC); 00425 wait_ms(MDC_WAIT); 00426 HAL_GPIO_ResetBits(GPIOx, MDC); 00427 } 00428 } 00429 00430 uint32_t input_MDIO( GPIO_TypeDef* GPIOx ) 00431 { 00432 uint32_t i, val=0; 00433 for(i=0; i<16; i++) 00434 { 00435 val <<=1; 00436 HAL_GPIO_SetBits(GPIOx, MDC); 00437 wait_ms(MDC_WAIT); 00438 HAL_GPIO_ResetBits(GPIOx, MDC); 00439 wait_ms(MDC_WAIT); 00440 val |= HAL_GPIO_ReadInputDataBit(GPIOx, MDIO); 00441 } 00442 return (val); 00443 } 00444 00445 void turnaround_MDIO( GPIO_TypeDef* GPIOx) 00446 { 00447 GPIOx->OUTENCLR = MDIO ; 00448 HAL_GPIO_SetBits(GPIOx, MDC); 00449 wait_ms(MDC_WAIT); 00450 HAL_GPIO_ResetBits(GPIOx, MDC); 00451 wait_ms(MDC_WAIT); 00452 } 00453 00454 void idle_MDIO( GPIO_TypeDef* GPIOx ) 00455 { 00456 GPIOx->OUTENSET = MDIO ; 00457 HAL_GPIO_SetBits(GPIOx,MDC); 00458 wait_ms(MDC_WAIT); 00459 HAL_GPIO_ResetBits(GPIOx, MDC); 00460 wait_ms(MDC_WAIT); 00461 } 00462 00463 uint32_t mdio_read(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr) 00464 { 00465 output_MDIO(GPIOx, 0xFFFFFFFF, 32); 00466 output_MDIO(GPIOx, 0x06, 4); 00467 output_MDIO(GPIOx, PHY_ADDR, 5); 00468 output_MDIO(GPIOx, PhyRegAddr, 5); 00469 turnaround_MDIO(GPIOx); 00470 uint32_t val = input_MDIO(GPIOx ); 00471 idle_MDIO(GPIOx); 00472 return val; 00473 } 00474 00475 void mdio_write(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr, uint32_t val) 00476 { 00477 output_MDIO(GPIOx, 0xFFFFFFFF, 32); 00478 output_MDIO(GPIOx, 0x05, 4); 00479 output_MDIO(GPIOx, PHY_ADDR, 5); 00480 output_MDIO(GPIOx, PhyRegAddr, 5); 00481 output_MDIO(GPIOx, 0x02, 2); 00482 output_MDIO(GPIOx, val, 16); 00483 idle_MDIO(GPIOx); 00484 } 00485 00486 int WIZnet_Chip::ethernet_link(void) { 00487 return ((mdio_read(GPIO_MDC, PHYREG_STATUS)>>SVAL)&0x01); 00488 } 00489 00490 void WIZnet_Chip::ethernet_set_link(int speed, int duplex) { 00491 uint32_t val=0; 00492 if((speed < 0) || (speed > 1)) { 00493 val = CNTL_AUTONEGO; 00494 } else { 00495 val = ((CNTL_SPEED&(speed<<11))|(CNTL_DUPLEX&(duplex<<7))); 00496 } 00497 mdio_write(GPIO_MDC, PHYREG_CONTROL, val); 00498 } 00499 00500 void WIZnet_Chip::reg_rd_mac(uint16_t addr, uint8_t* data) 00501 { 00502 data[0] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+3)); 00503 data[1] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+2)); 00504 data[2] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+1)); 00505 data[3] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+0)); 00506 data[4] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+7)); 00507 data[5] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+6)); 00508 } 00509 00510 void WIZnet_Chip::reg_wr_ip(uint16_t addr, uint8_t cb, const char* ip) 00511 { 00512 uint8_t buf[4]={0,}; 00513 uint32_t wr_ip = 0; 00514 char* p = (char*)ip; 00515 00516 for(int i = 0; i < 4; i++) { 00517 wr_ip = (wr_ip<<8); 00518 buf[i] = atoi(p); 00519 wr_ip |= buf[i]; 00520 p = strchr(p, '.'); 00521 if (p == NULL) break; 00522 p++; 00523 } 00524 *(volatile uint32_t *)(W7500x_WZTOE_BASE + (uint32_t)((cb<<16)+addr)) = wr_ip; 00525 } 00526 00527 void WIZnet_Chip::sreg_ip(int socket, uint16_t addr, const char* ip) { 00528 reg_wr_ip(addr, (uint8_t)(0x01+(socket<<2)), ip); 00529 } 00530 00531 #endif 00532
Generated on Wed Jul 13 2022 05:21:37 by
1.7.2
