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