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.
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.h" 00018 #if defined(TARGET_WIZwiki_W7500) || defined(TARGET_WIZwiki_W7500P) || defined(TARGET_WIZwiki_W7500ECO) 00019 00020 00021 #include "mbed.h" 00022 #include "mbed_debug.h" 00023 #include "DNSClient.h" 00024 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 00034 #if defined (TARGET_WIZwiki_W7500) || defined(TARGET_WIZwiki_W7500ECO) 00035 00036 #define MDIO GPIO_Pin_14 00037 #define MDC GPIO_Pin_15 00038 #define GPIO_MDC GPIOB 00039 #define PHY_ADDR_IP101G 0x07 00040 #define PHY_ADDR PHY_ADDR_IP101G 00041 #define SVAL 0x2 //right shift val = 2 00042 #define PHYREG_CONTROL 0x0 //Control Register address (Contorl basic register) 00043 #define PHYREG_STATUS 0x1 //Status Register address (Status basic register) 00044 #define CNTL_DUPLEX (0x01ul<< 7) 00045 #define CNTL_AUTONEGO (0x01ul<<11) 00046 #define CNTL_SPEED (0x01ul<<12) 00047 #define MDC_WAIT (1) 00048 00049 #elif defined (TARGET_WIZwiki_W7500P) 00050 00051 #define MDIO GPIO_Pin_15 00052 #define MDC GPIO_Pin_14 00053 #define GPIO_MDC GPIOB 00054 #define PHY_ADDR_IP101G 0x01 00055 #define PHY_ADDR PHY_ADDR_IP101G 00056 #define SVAL 0x2 //right shift val = 2 00057 #define PHYREG_CONTROL 0x0 //Control Register address (Contorl basic register) 00058 #define PHYREG_STATUS 0x1 //Status Register address (Status basic register) 00059 #define CNTL_DUPLEX (0x01ul<< 7) 00060 #define CNTL_AUTONEGO (0x01ul<<11) 00061 #define CNTL_SPEED (0x01ul<<12) 00062 #define MDC_WAIT (1) 00063 00064 #endif 00065 00066 void mdio_init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin_MDC, uint16_t GPIO_Pin_MDIO); 00067 void mdio_write(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr, uint32_t val); 00068 uint32_t mdio_read(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr); 00069 00070 WIZnet_Chip* WIZnet_Chip::inst; 00071 00072 WIZnet_Chip::WIZnet_Chip() 00073 { 00074 inst = this; 00075 } 00076 00077 bool WIZnet_Chip::setmac() 00078 { 00079 00080 for (int i =0; i < 6; i++) reg_wr<uint8_t>(SHAR+i, mac[i]); 00081 00082 return true; 00083 } 00084 00085 // Set the IP 00086 bool WIZnet_Chip::setip() 00087 { 00088 reg_wr<uint32_t>(SIPR, ip); 00089 reg_wr<uint32_t>(GAR, gateway); 00090 reg_wr<uint32_t>(SUBR, netmask); 00091 return true; 00092 } 00093 00094 bool WIZnet_Chip::setProtocol(int socket, Protocol p) 00095 { 00096 if (socket < 0) { 00097 return false; 00098 } 00099 sreg<uint8_t>(socket, Sn_MR, p); 00100 return true; 00101 } 00102 00103 bool WIZnet_Chip::connect(int socket, const char * host, int port, int timeout_ms) 00104 { 00105 if (socket < 0) { 00106 return false; 00107 } 00108 sreg<uint8_t>(socket, Sn_MR, TCP); 00109 scmd(socket, OPEN); 00110 sreg_ip(socket, Sn_DIPR, host); 00111 sreg<uint16_t>(socket, Sn_DPORT, port); 00112 sreg<uint16_t>(socket, Sn_PORT, new_port()); 00113 scmd(socket, CONNECT); 00114 Timer t; 00115 t.reset(); 00116 t.start(); 00117 while(!is_connected(socket)) { 00118 if (t.read_ms() > timeout_ms) { 00119 return false; 00120 } 00121 } 00122 return true; 00123 } 00124 00125 bool WIZnet_Chip::gethostbyname(const char* host, uint32_t* ip) 00126 { 00127 uint32_t addr = str_to_ip(host); 00128 char buf[17]; 00129 snprintf(buf, sizeof(buf), "%d.%d.%d.%d", 00130 (uint8_t)((addr>>24)&0xff), 00131 (uint8_t)((addr>>16)&0xff), 00132 (uint8_t)((addr>>8)&0xff), 00133 (uint8_t)(addr&0xff)); 00134 if (strcmp(buf, host) == 0) { 00135 *ip = addr; 00136 return true; 00137 } 00138 DNSClient client; 00139 if(client.lookup(host)) { 00140 *ip = client.ip; 00141 return true; 00142 } 00143 return false; 00144 } 00145 00146 00147 bool WIZnet_Chip::is_connected(int socket) 00148 { 00149 /* 00150 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_ESTABLISHED) { 00151 return true; 00152 } 00153 */ 00154 uint8_t tmpSn_SR; 00155 tmpSn_SR = sreg<uint8_t>(socket, Sn_SR); 00156 // packet sending is possible, when state is SOCK_CLOSE_WAIT. 00157 if ((tmpSn_SR == SOCK_ESTABLISHED) || (tmpSn_SR == SOCK_CLOSE_WAIT)) { 00158 return true; 00159 } 00160 return false; 00161 } 00162 // Reset the chip & set the buffer 00163 void WIZnet_Chip::reset() 00164 { 00165 /* S/W Reset PHY */ 00166 mdio_write(GPIO_MDC, PHYREG_CONTROL, 0x8000); 00167 wait_ms(10);//for S/W reset 00168 wait_ms(10);//for MDC I/F RDY 00169 00170 mdio_init(GPIO_MDC, MDC, MDIO); 00171 00172 /* S/W Reset WZTOE */ 00173 reg_wr<uint8_t>(MR, MR_RST); 00174 // set PAD strengh and pull-up for TXD[3:0] and TXE 00175 #ifdef __DEF_USED_IC101AG__ //For using IC+101AG 00176 00177 #if defined(TARGET_WIZwiki_W7500) || defined(TARGET_WIZwiki_W7500ECO) 00178 00179 *(volatile uint32_t *)(0x41003068) = 0x64; //TXD0 00180 *(volatile uint32_t *)(0x4100306C) = 0x64; //TXD1 00181 *(volatile uint32_t *)(0x41003070) = 0x64; //TXD2 00182 *(volatile uint32_t *)(0x41003074) = 0x64; //TXD3 00183 *(volatile uint32_t *)(0x41003050) = 0x64; //TXE 00184 #endif 00185 00186 #endif 00187 00188 // set ticker counter 00189 reg_wr<uint32_t>(TIC100US, (SystemCoreClock/10000)); 00190 // write MAC address inside the WZTOE MAC address register 00191 reg_wr_mac(SHAR, mac); 00192 /* 00193 * set RX and TX buffer size 00194 * for (int socket = 0; socket < MAX_SOCK_NUM; socket++) { 00195 * sreg<uint8_t>(socket, Sn_RXBUF_SIZE, 2); 00196 * sreg<uint8_t>(socket, Sn_TXBUF_SIZE, 2); 00197 * } 00198 */ 00199 } 00200 00201 00202 bool WIZnet_Chip::close(int socket) 00203 { 00204 if (socket < 0) { 00205 return false; 00206 } 00207 // if SOCK_CLOSED, return 00208 if (sreg<uint8_t>(socket, Sn_SR) == SOCK_CLOSED) { 00209 return true; 00210 } 00211 // if SOCK_ESTABLISHED, send FIN-Packet to peer 00212 if (sreg<uint8_t>(socket, Sn_MR) == TCP) { 00213 scmd(socket, DISCON); 00214 } 00215 // close socket 00216 scmd(socket, CLOSE); 00217 // clear Socket Interrupt Register 00218 sreg<uint8_t>(socket, Sn_ICR, 0xff); 00219 return true; 00220 } 00221 00222 int WIZnet_Chip::wait_readable(int socket, int wait_time_ms, int req_size) 00223 { 00224 if (socket < 0) { 00225 return -1; 00226 } 00227 Timer t; 00228 t.reset(); 00229 t.start(); 00230 while(1) { 00231 int size = sreg<uint16_t>(socket, Sn_RX_RSR); 00232 if (size > req_size) { 00233 return size; 00234 } 00235 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00236 break; 00237 } 00238 } 00239 return -1; 00240 } 00241 00242 int WIZnet_Chip::wait_writeable(int socket, int wait_time_ms, int req_size) 00243 { 00244 if (socket < 0) { 00245 return -1; 00246 } 00247 Timer t; 00248 t.reset(); 00249 t.start(); 00250 while(1) { 00251 int size = sreg<uint16_t>(socket, Sn_TX_FSR); 00252 if (size > req_size) { 00253 return size; 00254 } 00255 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00256 break; 00257 } 00258 } 00259 return -1; 00260 } 00261 00262 int WIZnet_Chip::send(int socket, const char * str, int len) 00263 { 00264 if (socket < 0) { 00265 return -1; 00266 } 00267 00268 uint16_t ptr = sreg<uint16_t>(socket, Sn_TX_WR); 00269 uint32_t sn_tx_base = W7500x_TXMEM_BASE + (uint32_t)(socket<<18); 00270 00271 for(int i=0; i<len; i++) 00272 *(volatile uint8_t *)(sn_tx_base + ((ptr+i)&0xFFFF)) = str[i]; 00273 00274 sreg<uint16_t>(socket, Sn_TX_WR, ptr + len); 00275 scmd(socket, SEND); 00276 00277 uint8_t tmp_Sn_IR; 00278 while (( (tmp_Sn_IR = sreg<uint8_t>(socket, Sn_IR)) & INT_SEND_OK) != INT_SEND_OK) { 00279 // @Jul.10, 2014 fix contant name, and udp sendto function. 00280 switch (sreg<uint8_t>(socket, Sn_SR)) { 00281 case SOCK_CLOSED : 00282 close(socket); 00283 return 0; 00284 //break; 00285 case SOCK_UDP : 00286 // ARP timeout is possible. 00287 if ((tmp_Sn_IR & INT_TIMEOUT) == INT_TIMEOUT) { 00288 sreg<uint8_t>(socket, Sn_ICR, INT_TIMEOUT); 00289 return 0; 00290 } 00291 break; 00292 default : 00293 break; 00294 } 00295 } 00296 00297 sreg<uint8_t>(socket, Sn_ICR, INT_SEND_OK); 00298 00299 return len; 00300 } 00301 00302 int WIZnet_Chip::recv(int socket, char* buf, int len) 00303 { 00304 if (socket < 0) { 00305 return -1; 00306 } 00307 uint16_t ptr = sreg<uint16_t>(socket, Sn_RX_RD); 00308 uint32_t sn_rx_base = W7500x_RXMEM_BASE + (uint32_t)(socket<<18); 00309 00310 for(int i=0; i<len; i++) 00311 buf[i] = *(volatile uint8_t *)(sn_rx_base + ((ptr+i)&0xFFFF)); 00312 00313 sreg<uint16_t>(socket, Sn_RX_RD, ptr + len); 00314 scmd(socket, RECV); 00315 00316 return len; 00317 } 00318 00319 int WIZnet_Chip::new_socket() 00320 { 00321 for(int s = 0; s < MAX_SOCK_NUM; s++) { 00322 if (sreg<uint8_t>(s, Sn_SR) == SOCK_CLOSED) { 00323 return s; 00324 } 00325 } 00326 return -1; 00327 } 00328 00329 uint16_t WIZnet_Chip::new_port() 00330 { 00331 uint16_t port = rand(); 00332 port |= 49152; 00333 return port; 00334 } 00335 00336 bool WIZnet_Chip::link(int wait_time_ms) 00337 { 00338 Timer t; 00339 t.reset(); 00340 t.start(); 00341 while(1) { 00342 int is_link = ethernet_link(); 00343 00344 if (is_link) { 00345 return true; 00346 } 00347 if (wait_time_ms != (-1) && t.read_ms() > wait_time_ms) { 00348 break; 00349 } 00350 } 00351 return 0; 00352 } 00353 00354 void WIZnet_Chip::set_link(PHYMode phymode) 00355 { 00356 int speed = -1; 00357 int duplex = 0; 00358 00359 switch(phymode) { 00360 case AutoNegotiate : speed = -1; duplex = 0; break; 00361 case HalfDuplex10 : speed = 0; duplex = 0; break; 00362 case FullDuplex10 : speed = 0; duplex = 1; break; 00363 case HalfDuplex100 : speed = 1; duplex = 0; break; 00364 case FullDuplex100 : speed = 1; duplex = 1; break; 00365 } 00366 00367 ethernet_set_link(speed, duplex); 00368 } 00369 00370 uint32_t str_to_ip(const char* str) 00371 { 00372 uint32_t ip = 0; 00373 char* p = (char*)str; 00374 for(int i = 0; i < 4; i++) { 00375 ip |= atoi(p); 00376 p = strchr(p, '.'); 00377 if (p == NULL) { 00378 break; 00379 } 00380 ip <<= 8; 00381 p++; 00382 } 00383 return ip; 00384 } 00385 00386 void printfBytes(char* str, uint8_t* buf, int len) 00387 { 00388 printf("%s %d:", str, len); 00389 for(int i = 0; i < len; i++) { 00390 printf(" %02x", buf[i]); 00391 } 00392 printf("\n"); 00393 } 00394 00395 void printHex(uint8_t* buf, int len) 00396 { 00397 for(int i = 0; i < len; i++) { 00398 if ((i%16) == 0) { 00399 printf("%p", buf+i); 00400 } 00401 printf(" %02x", buf[i]); 00402 if ((i%16) == 15) { 00403 printf("\n"); 00404 } 00405 } 00406 printf("\n"); 00407 } 00408 00409 void debug_hex(uint8_t* buf, int len) 00410 { 00411 for(int i = 0; i < len; i++) { 00412 if ((i%16) == 0) { 00413 debug("%p", buf+i); 00414 } 00415 debug(" %02x", buf[i]); 00416 if ((i%16) == 15) { 00417 debug("\n"); 00418 } 00419 } 00420 debug("\n"); 00421 } 00422 00423 void WIZnet_Chip::scmd(int socket, Command cmd) 00424 { 00425 sreg<uint8_t>(socket, Sn_CR, cmd); 00426 while(sreg<uint8_t>(socket, Sn_CR)); 00427 } 00428 00429 00430 void mdio_init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin_MDC, uint16_t GPIO_Pin_MDIO) 00431 { 00432 /* Set GPIOs for MDIO and MDC */ 00433 GPIO_InitTypeDef MDIO_InitDef; 00434 HAL_PAD_AFConfig(PAD_PB, GPIO_Pin_MDIO, PAD_AF1); 00435 HAL_PAD_AFConfig(PAD_PB, GPIO_Pin_MDC, PAD_AF1); 00436 MDIO_InitDef.GPIO_Pin = GPIO_Pin_MDC | GPIO_Pin_MDIO; 00437 MDIO_InitDef.GPIO_Mode = GPIO_Mode_OUT; 00438 HAL_GPIO_Init(GPIOx, &MDIO_InitDef); 00439 } 00440 00441 void output_MDIO(GPIO_TypeDef* GPIOx, uint32_t val, uint32_t n) 00442 { 00443 for(val <<= (32-n); n; val<<=1, n--) 00444 { 00445 if(val & 0x80000000) 00446 HAL_GPIO_SetBits(GPIOx, MDIO); 00447 else 00448 HAL_GPIO_ResetBits(GPIOx, MDIO); 00449 00450 wait_ms(MDC_WAIT); 00451 HAL_GPIO_SetBits(GPIOx, MDC); 00452 wait_ms(MDC_WAIT); 00453 HAL_GPIO_ResetBits(GPIOx, MDC); 00454 } 00455 } 00456 00457 uint32_t input_MDIO( GPIO_TypeDef* GPIOx ) 00458 { 00459 uint32_t i, val=0; 00460 for(i=0; i<16; i++) 00461 { 00462 val <<=1; 00463 HAL_GPIO_SetBits(GPIOx, MDC); 00464 wait_ms(MDC_WAIT); 00465 HAL_GPIO_ResetBits(GPIOx, MDC); 00466 wait_ms(MDC_WAIT); 00467 val |= HAL_GPIO_ReadInputDataBit(GPIOx, MDIO); 00468 } 00469 return (val); 00470 } 00471 00472 void turnaround_MDIO( GPIO_TypeDef* GPIOx) 00473 { 00474 GPIOx->OUTENCLR = MDIO ; 00475 HAL_GPIO_SetBits(GPIOx, MDC); 00476 wait_ms(MDC_WAIT); 00477 HAL_GPIO_ResetBits(GPIOx, MDC); 00478 wait_ms(MDC_WAIT); 00479 } 00480 00481 void idle_MDIO( GPIO_TypeDef* GPIOx ) 00482 { 00483 GPIOx->OUTENSET = MDIO ; 00484 HAL_GPIO_SetBits(GPIOx,MDC); 00485 wait_ms(MDC_WAIT); 00486 HAL_GPIO_ResetBits(GPIOx, MDC); 00487 wait_ms(MDC_WAIT); 00488 } 00489 00490 uint32_t mdio_read(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr) 00491 { 00492 output_MDIO(GPIOx, 0xFFFFFFFF, 32); 00493 output_MDIO(GPIOx, 0x06, 4); 00494 output_MDIO(GPIOx, PHY_ADDR, 5); 00495 output_MDIO(GPIOx, PhyRegAddr, 5); 00496 turnaround_MDIO(GPIOx); 00497 uint32_t val = input_MDIO(GPIOx ); 00498 idle_MDIO(GPIOx); 00499 return val; 00500 } 00501 00502 void mdio_write(GPIO_TypeDef* GPIOx, uint32_t PhyRegAddr, uint32_t val) 00503 { 00504 output_MDIO(GPIOx, 0xFFFFFFFF, 32); 00505 output_MDIO(GPIOx, 0x05, 4); 00506 output_MDIO(GPIOx, PHY_ADDR, 5); 00507 output_MDIO(GPIOx, PhyRegAddr, 5); 00508 output_MDIO(GPIOx, 0x02, 2); 00509 output_MDIO(GPIOx, val, 16); 00510 idle_MDIO(GPIOx); 00511 } 00512 00513 int WIZnet_Chip::ethernet_link(void) { 00514 return ((mdio_read(GPIO_MDC, PHYREG_STATUS)>>SVAL)&0x01); 00515 } 00516 00517 void WIZnet_Chip::ethernet_set_link(int speed, int duplex) { 00518 uint32_t val=0; 00519 if((speed < 0) || (speed > 1)) { 00520 val = CNTL_AUTONEGO; 00521 } else { 00522 val = ((CNTL_SPEED&(speed<<11))|(CNTL_DUPLEX&(duplex<<7))); 00523 } 00524 mdio_write(GPIO_MDC, PHYREG_CONTROL, val); 00525 } 00526 00527 void WIZnet_Chip::reg_rd_mac(uint16_t addr, uint8_t* data) 00528 { 00529 data[0] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+3)); 00530 data[1] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+2)); 00531 data[2] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+1)); 00532 data[3] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+0)); 00533 data[4] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+7)); 00534 data[5] = *(volatile uint8_t *)(W7500x_WZTOE_BASE + (uint32_t)(addr+6)); 00535 } 00536 00537 void WIZnet_Chip::reg_wr_ip(uint16_t addr, uint8_t cb, const char* ip) 00538 { 00539 uint8_t buf[4]={0,}; 00540 uint32_t wr_ip = 0; 00541 char* p = (char*)ip; 00542 00543 for(int i = 0; i < 4; i++) { 00544 wr_ip = (wr_ip<<8); 00545 buf[i] = atoi(p); 00546 wr_ip |= buf[i]; 00547 p = strchr(p, '.'); 00548 if (p == NULL) break; 00549 p++; 00550 } 00551 *(volatile uint32_t *)(W7500x_WZTOE_BASE + (uint32_t)((cb<<16)+addr)) = wr_ip; 00552 } 00553 00554 void WIZnet_Chip::sreg_ip(int socket, uint16_t addr, const char* ip) { 00555 reg_wr_ip(addr, (uint8_t)(0x01+(socket<<2)), ip); 00556 } 00557 00558 #endif 00559 00560
Generated on Sat Jul 16 2022 06:28:25 by
1.7.2
